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 )