YATT-Lite
view release on metacpan or search on metacpan
Lite/LanguageServer/SpecParser.pm view on Meta::CPAN
}
unless ($self->eat_token(']', $bodyTokList)) {
$self->tokerror(["Tuple not closed for declbody of ", $decl], $bodyTokList);
}
return $expr;
} else {
die "Really? ".MOP4Import::Util::terse_dump($bodyTokList, [decl => $decl]);
}
}
sub parse_declarator :method {
(my MY $self, my $declTokIn) = @_;
my $declTok = [@$declTokIn];
my Decl $decl = {};
if ($self->eat_token(export => $declTok)) {
$decl->{exported} = 1;
}
$decl->{kind} = shift @$declTok;
$decl->{name} = shift @$declTok;
if ($decl->{kind} eq 'interface') {
if ($self->eat_token(extends => $declTok)) {
my Interface $if = $decl;
$if->{extends} = shift @$declTok;
}
}
$decl;
}
sub eat_token :method {
(my MY $self, my ($tokString, $tokList)) = @_;
if (@$tokList and $tokList->[0] eq $tokString) {
shift @$tokList;
}
}
sub re_match_token :method {
(my MY $self, my ($pattern, $tokList)) = @_;
if (@$tokList and my @match = ($tokList->[0] =~ $pattern)) {
shift @$tokList;
return @match;
}
return ();
}
#----------------------------------------
sub tokenize_statement_list :method {
(my MY $self, my $statementList) = @_;
map {
my ($declarator, $comment, $body) = @$_;
[$self->tokenize_declarator($declarator)
, $self->tokenize_comment_block($comment)
, $self->tokenize_declbody($body)];
} @$statementList;
}
sub tokenize_declbody :method {
(my MY $self, my $declString) = @_;
[map {s/\s*\z//; $_}
grep {/\S/}
split m{(; | [{}(),\|&:]
| \[ (?=[^]]) | (?<!\[) \]
| /\*\*\n(?:.*?)\*/ | //[^\n]*\n) \s*}xs, $declString];
}
sub tokenize_comment_block :method {
(my MY $self, my $commentString) = @_;
return undef unless defined $commentString;
unless ($commentString =~ s,^\s*/\*\*\n,,s) {
Carp::croak "Comment doesn't start with /**\\n: "
. MOP4Import::Util::terse_dump($commentString);
}
unless ($commentString =~ s,\*/\n?\z,,s) {
Carp::croak "Comment doesn't end with */: "
. MOP4Import::Util::terse_dump($commentString);
}
$commentString =~ s/^\s+\*\ //mg;
$commentString =~ s/\s+\z//;
$commentString;
}
sub tokenize_declarator :method {
(my MY $self, my $declString) = @_;
[split " ", $declString];
}
sub extract_statement_list :method {
(my MY $self, my ($codeList)) = @_;
local $_;
my $wordRe = qr{[^\s{}=\|]+};
my $commentRe = qr{/\*\*\n(?:.*?)\*/\n?}sx;
my $groupRe = qr{( \{ (?: (?> [^{}/]+) | $commentRe | /[^\*] | (?-1) )* \} )}x;
my $typeElemRe = qr{$wordRe | $groupRe}sx;
my @result;
foreach (@$codeList) {
while (m{
\G
\s*
(?<comment>$commentRe)?
(?<decl>(?:$wordRe\s+)+)
(?: (?<body> $groupRe )
| = \s* (?<type>
$typeElemRe \s*(?: \| \s*$typeElemRe)*
)
\s*;
)
}sgx) {
push @result, [$+{decl}, $+{comment}, $+{body} // $+{type}];
}
}
@result;
}
# Lite/LanguageServer/SpecParser.pm --flatten --output=raw extract_codeblock typescript specification.md
sub extract_codeblock :method {
(my MY $self, my $langId, local @ARGV) = @_;
local $_;
my ($chunk, @result);
while (defined($_ = $self->cli_compat_diamond)) {
my $line = s{^```$langId\b}{} .. s{^```}{}
or next;
( run in 1.055 second using v1.01-cache-2.11-cpan-71847e10f99 )