Parser.cpp revision 344779
178189Sbrian//===- Parser.cpp - Matcher expression parser -----------------------------===//
278189Sbrian//
378189Sbrian//                     The LLVM Compiler Infrastructure
478189Sbrian//
578189Sbrian// This file is distributed under the University of Illinois Open Source
66059Samurai// License. See LICENSE.TXT for details.
778189Sbrian//
878189Sbrian//===----------------------------------------------------------------------===//
978189Sbrian///
1078189Sbrian/// \file
1178189Sbrian/// Recursive parser implementation for the matcher expression grammar.
1278189Sbrian///
1378189Sbrian//===----------------------------------------------------------------------===//
1478189Sbrian
156059Samurai#include "clang/ASTMatchers/Dynamic/Parser.h"
1678189Sbrian#include "clang/ASTMatchers/ASTMatchersInternal.h"
1778189Sbrian#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
1878189Sbrian#include "clang/ASTMatchers/Dynamic/Registry.h"
1978189Sbrian#include "clang/Basic/CharInfo.h"
2078189Sbrian#include "llvm/ADT/Optional.h"
2178189Sbrian#include "llvm/ADT/StringRef.h"
2278189Sbrian#include "llvm/Support/ErrorHandling.h"
2378189Sbrian#include "llvm/Support/ManagedStatic.h"
2478189Sbrian#include <algorithm>
2578189Sbrian#include <cassert>
2678189Sbrian#include <cerrno>
276059Samurai#include <cstddef>
2850479Speter#include <cstdlib>
296059Samurai#include <string>
3078189Sbrian#include <utility>
3143313Sbrian#include <vector>
3230715Sbrian
3326031Sbriannamespace clang {
3430715Sbriannamespace ast_matchers {
3526031Sbriannamespace dynamic {
3630715Sbrian
3726031Sbrian/// Simple structure to hold information for one token from the parser.
3830715Sbrianstruct Parser::TokenInfo {
3936285Sbrian  /// Different possible tokens.
4030715Sbrian  enum TokenKind {
4138628Sbrian    TK_Eof,
4230715Sbrian    TK_OpenParen,
4326516Sbrian    TK_CloseParen,
4430715Sbrian    TK_Comma,
45102500Sbrian    TK_Period,
4630715Sbrian    TK_Literal,
4730715Sbrian    TK_Ident,
4830715Sbrian    TK_InvalidChar,
4930715Sbrian    TK_Error,
5030715Sbrian    TK_CodeCompletion
5130715Sbrian  };
5230715Sbrian
5350059Sbrian  /// Some known identifiers.
5458037Sbrian  static const char* const ID_Bind;
5558037Sbrian
5658037Sbrian  TokenInfo() = default;
5746086Sbrian
5839395Sbrian  StringRef Text;
5939395Sbrian  TokenKind Kind = TK_Eof;
6058037Sbrian  SourceRange Range;
6146686Sbrian  VariantValue Value;
6237009Sbrian};
6331343Sbrian
6430715Sbrianconst char* const Parser::TokenInfo::ID_Bind = "bind";
6530715Sbrian
6630715Sbrian/// Simple tokenizer for the parser.
676059Samuraiclass Parser::CodeTokenizer {
6831690Sbrianpublic:
6936285Sbrian  explicit CodeTokenizer(StringRef MatcherCode, Diagnostics *Error)
7036285Sbrian      : Code(MatcherCode), StartOfLine(MatcherCode), Error(Error) {
7138557Sbrian    NextToken = getNextToken();
7238557Sbrian  }
7363484Sbrian
7481634Sbrian  CodeTokenizer(StringRef MatcherCode, Diagnostics *Error,
756059Samurai                unsigned CodeCompletionOffset)
7650059Sbrian      : Code(MatcherCode), StartOfLine(MatcherCode), Error(Error),
7751075Sbrian        CodeCompletionLocation(MatcherCode.data() + CodeCompletionOffset) {
7831343Sbrian    NextToken = getNextToken();
7925630Sbrian  }
8036285Sbrian
8136285Sbrian  /// Returns but doesn't consume the next token.
8230715Sbrian  const TokenInfo &peekNextToken() const { return NextToken; }
8330715Sbrian
8430715Sbrian  /// Consumes and returns the next token.
8531080Sbrian  TokenInfo consumeNextToken() {
8636285Sbrian    TokenInfo ThisToken = NextToken;
8736285Sbrian    NextToken = getNextToken();
8836285Sbrian    return ThisToken;
8936285Sbrian  }
9043313Sbrian
9143313Sbrian  TokenInfo::TokenKind nextTokenKind() const { return NextToken.Kind; }
9243313Sbrian
9381634Sbrianprivate:
9481634Sbrian  TokenInfo getNextToken() {
9536285Sbrian    consumeWhitespace();
9636285Sbrian    TokenInfo Result;
9736285Sbrian    Result.Range.Start = currentLocation();
9836285Sbrian
9936285Sbrian    if (CodeCompletionLocation && CodeCompletionLocation <= Code.data()) {
10038174Sbrian      Result.Kind = TokenInfo::TK_CodeCompletion;
10136285Sbrian      Result.Text = StringRef(CodeCompletionLocation, 0);
10240561Sbrian      CodeCompletionLocation = nullptr;
10353298Sbrian      return Result;
10481697Sbrian    }
1056059Samurai
10636285Sbrian    if (Code.empty()) {
10736285Sbrian      Result.Kind = TokenInfo::TK_Eof;
10836285Sbrian      Result.Text = "";
10936285Sbrian      return Result;
11036285Sbrian    }
11136285Sbrian
11236285Sbrian    switch (Code[0]) {
11336285Sbrian    case '#':
11436285Sbrian      Result.Kind = TokenInfo::TK_Eof;
11536285Sbrian      Result.Text = "";
11636285Sbrian      return Result;
11736285Sbrian    case ',':
11836285Sbrian      Result.Kind = TokenInfo::TK_Comma;
11936285Sbrian      Result.Text = Code.substr(0, 1);
12036285Sbrian      Code = Code.drop_front();
12136285Sbrian      break;
12236285Sbrian    case '.':
12336285Sbrian      Result.Kind = TokenInfo::TK_Period;
12436285Sbrian      Result.Text = Code.substr(0, 1);
12536285Sbrian      Code = Code.drop_front();
12636285Sbrian      break;
12736285Sbrian    case '(':
12836285Sbrian      Result.Kind = TokenInfo::TK_OpenParen;
12936285Sbrian      Result.Text = Code.substr(0, 1);
13036285Sbrian      Code = Code.drop_front();
13138174Sbrian      break;
13238174Sbrian    case ')':
13338544Sbrian      Result.Kind = TokenInfo::TK_CloseParen;
13440665Sbrian      Result.Text = Code.substr(0, 1);
13540665Sbrian      Code = Code.drop_front();
13643313Sbrian      break;
13744073Sbrian
13846686Sbrian    case '"':
13946686Sbrian    case '\'':
14050867Sbrian      // Parse a string literal.
14152488Sbrian      consumeStringLiteral(&Result);
14261534Sbrian      break;
14378411Sbrian
144102558Sbrian    case '0': case '1': case '2': case '3': case '4':
145132273Sbrian    case '5': case '6': case '7': case '8': case '9':
146132818Sglebius      // Parse an unsigned and float literal.
1476059Samurai      consumeNumberLiteral(&Result);
14836285Sbrian      break;
14936285Sbrian
15036285Sbrian    default:
15136285Sbrian      if (isAlphanumeric(Code[0])) {
15236285Sbrian        // Parse an identifier
15336285Sbrian        size_t TokenLength = 1;
15444106Sbrian        while (true) {
15544106Sbrian          // A code completion location in/immediately after an identifier will
15644106Sbrian          // cause the portion of the identifier before the code completion
15744106Sbrian          // location to become a code completion token.
15847858Sbrian          if (CodeCompletionLocation == Code.data() + TokenLength) {
159138799Sbrian            CodeCompletionLocation = nullptr;
160138799Sbrian            Result.Kind = TokenInfo::TK_CodeCompletion;
161138799Sbrian            Result.Text = Code.substr(0, TokenLength);
162138799Sbrian            Code = Code.drop_front(TokenLength);
163138799Sbrian            return Result;
164138799Sbrian          }
165138799Sbrian          if (TokenLength == Code.size() || !isAlphanumeric(Code[TokenLength]))
166138799Sbrian            break;
167138799Sbrian          ++TokenLength;
168138799Sbrian        }
169138799Sbrian        if (TokenLength == 4 && Code.startswith("true")) {
17036285Sbrian          Result.Kind = TokenInfo::TK_Literal;
171138799Sbrian          Result.Value = true;
17236285Sbrian        } else if (TokenLength == 5 && Code.startswith("false")) {
17336285Sbrian          Result.Kind = TokenInfo::TK_Literal;
17436285Sbrian          Result.Value = false;
17536285Sbrian        } else {
17636285Sbrian          Result.Kind = TokenInfo::TK_Ident;
17736285Sbrian          Result.Text = Code.substr(0, TokenLength);
17836285Sbrian        }
17936285Sbrian        Code = Code.drop_front(TokenLength);
18036285Sbrian      } else {
18136285Sbrian        Result.Kind = TokenInfo::TK_InvalidChar;
18236285Sbrian        Result.Text = Code.substr(0, 1);
18336285Sbrian        Code = Code.drop_front(1);
18436934Sbrian      }
18540561Sbrian      break;
18640561Sbrian    }
18740561Sbrian
18840561Sbrian    Result.Range.End = currentLocation();
18940679Sbrian    return Result;
19050059Sbrian  }
19158867Sbrian
19258867Sbrian  /// Consume an unsigned and float literal.
19331343Sbrian  void consumeNumberLiteral(TokenInfo *Result) {
1946059Samurai    bool isFloatingLiteral = false;
19536285Sbrian    unsigned Length = 1;
19636285Sbrian    if (Code.size() > 1) {
19736285Sbrian      // Consume the 'x' or 'b' radix modifier, if present.
19836285Sbrian      switch (toLowercase(Code[1])) {
19936285Sbrian      case 'x': case 'b': Length = 2;
20036285Sbrian      }
20136285Sbrian    }
20236285Sbrian    while (Length < Code.size() && isHexDigit(Code[Length]))
20336285Sbrian      ++Length;
20436285Sbrian
20536285Sbrian    // Try to recognize a floating point literal.
2066059Samurai    while (Length < Code.size()) {
20731343Sbrian      char c = Code[Length];
2086059Samurai      if (c == '-' || c == '+' || c == '.' || isHexDigit(c)) {
20928679Sbrian        isFloatingLiteral = true;
21036285Sbrian        Length++;
21136285Sbrian      } else {
2126059Samurai        break;
21336285Sbrian      }
21436285Sbrian    }
21526516Sbrian
21636285Sbrian    Result->Text = Code.substr(0, Length);
21726516Sbrian    Code = Code.drop_front(Length);
21836285Sbrian
21936285Sbrian    if (isFloatingLiteral) {
22036285Sbrian      char *end;
22136285Sbrian      errno = 0;
22236285Sbrian      std::string Text = Result->Text.str();
22336285Sbrian      double doubleValue = strtod(Text.c_str(), &end);
22428679Sbrian      if (*end == 0 && errno == 0) {
2256059Samurai        Result->Kind = TokenInfo::TK_Literal;
22626516Sbrian        Result->Value = doubleValue;
2276059Samurai        return;
22836285Sbrian      }
22931372Sbrian    } else {
23036285Sbrian      unsigned Value;
23136285Sbrian      if (!Result->Text.getAsInteger(0, Value)) {
23236285Sbrian        Result->Kind = TokenInfo::TK_Literal;
23331372Sbrian        Result->Value = Value;
23431372Sbrian        return;
23531372Sbrian      }
23631372Sbrian    }
23731372Sbrian
23831372Sbrian    SourceRange Range;
2396059Samurai    Range.Start = Result->Range.Start;
24036285Sbrian    Range.End = currentLocation();
24136285Sbrian    Error->addError(Range, Error->ET_ParserNumberError) << Result->Text;
24236285Sbrian    Result->Kind = TokenInfo::TK_Error;
24336285Sbrian  }
24436285Sbrian
24536285Sbrian  /// Consume a string literal.
24640482Sbrian  ///
24740482Sbrian  /// \c Code must be positioned at the start of the literal (the opening
24840482Sbrian  /// quote). Consumed until it finds the same closing quote character.
24936285Sbrian  void consumeStringLiteral(TokenInfo *Result) {
25031372Sbrian    bool InEscape = false;
25136285Sbrian    const char Marker = Code[0];
2526059Samurai    for (size_t Length = 1, Size = Code.size(); Length != Size; ++Length) {
25331372Sbrian      if (InEscape) {
25436285Sbrian        InEscape = false;
25526516Sbrian        continue;
25626516Sbrian      }
2576059Samurai      if (Code[Length] == '\\') {
2586059Samurai        InEscape = true;
25936285Sbrian        continue;
26063484Sbrian      }
26163484Sbrian      if (Code[Length] == Marker) {
26285991Sbrian        Result->Kind = TokenInfo::TK_Literal;
26385991Sbrian        Result->Text = Code.substr(0, Length + 1);
26485991Sbrian        Result->Value = Code.substr(1, Length - 1);
26563484Sbrian        Code = Code.drop_front(Length + 1);
26663484Sbrian        return;
26763484Sbrian      }
26863484Sbrian    }
26963484Sbrian
27063484Sbrian    StringRef ErrorText = Code;
27163484Sbrian    Code = Code.drop_front(Code.size());
27263484Sbrian    SourceRange Range;
27363484Sbrian    Range.Start = Result->Range.Start;
27463484Sbrian    Range.End = currentLocation();
27563484Sbrian    Error->addError(Range, Error->ET_ParserStringError) << ErrorText;
27663484Sbrian    Result->Kind = TokenInfo::TK_Error;
27763484Sbrian  }
27863484Sbrian
27936285Sbrian  /// Consume all leading whitespace from \c Code.
2806059Samurai  void consumeWhitespace() {
28136285Sbrian    while (!Code.empty() && isWhitespace(Code[0])) {
28236285Sbrian      if (Code[0] == '\n') {
28336285Sbrian        ++Line;
2846059Samurai        StartOfLine = Code.drop_front();
28536285Sbrian      }
28636285Sbrian      Code = Code.drop_front();
28736285Sbrian    }
28836285Sbrian  }
28936285Sbrian
29036285Sbrian  SourceLocation currentLocation() {
29136285Sbrian    SourceLocation Location;
29236285Sbrian    Location.Line = Line;
2936059Samurai    Location.Column = Code.data() - StartOfLine.data() + 1;
29436285Sbrian    return Location;
29536285Sbrian  }
2966059Samurai
2976059Samurai  StringRef Code;
2986059Samurai  StringRef StartOfLine;
29936285Sbrian  unsigned Line = 1;
3006059Samurai  Diagnostics *Error;
30136285Sbrian  TokenInfo NextToken;
30236285Sbrian  const char *CodeCompletionLocation = nullptr;
30311336Samurai};
30436285Sbrian
30536285SbrianParser::Sema::~Sema() = default;
30636285Sbrian
3076059Samuraistd::vector<ArgKind> Parser::Sema::getAcceptedCompletionTypes(
30826516Sbrian    llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context) {
30936285Sbrian  return {};
31036285Sbrian}
31136285Sbrian
31232711Sbrianstd::vector<MatcherCompletion>
31336285SbrianParser::Sema::getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) {
31436285Sbrian  return {};
31536285Sbrian}
31636285Sbrian
31736285Sbrianstruct Parser::ScopedContextEntry {
31831121Sbrian  Parser *P;
31936285Sbrian
32036285Sbrian  ScopedContextEntry(Parser *P, MatcherCtor C) : P(P) {
32136285Sbrian    P->ContextStack.push_back(std::make_pair(C, 0u));
32298243Sbrian  }
32336285Sbrian
32436285Sbrian  ~ScopedContextEntry() {
32536285Sbrian    P->ContextStack.pop_back();
32636285Sbrian  }
32785991Sbrian
32836285Sbrian  void nextArg() {
32936285Sbrian    ++P->ContextStack.back().second;
33040797Sbrian  }
33140797Sbrian};
33236285Sbrian
33340797Sbrian/// Parse expressions that start with an identifier.
33436285Sbrian///
33540797Sbrian/// This function can parse named values and matchers.
33640797Sbrian/// In case of failure it will try to determine the user's intent to give
33740797Sbrian/// an appropriate error message.
33840797Sbrianbool Parser::parseIdentifierPrefixImpl(VariantValue *Value) {
33940797Sbrian  const TokenInfo NameToken = Tokenizer->consumeNextToken();
34040797Sbrian
34140797Sbrian  if (Tokenizer->nextTokenKind() != TokenInfo::TK_OpenParen) {
34240797Sbrian    // Parse as a named value.
34340797Sbrian    if (const VariantValue NamedValue =
34440797Sbrian            NamedValues ? NamedValues->lookup(NameToken.Text)
34540797Sbrian                        : VariantValue()) {
34640797Sbrian
34740797Sbrian      if (Tokenizer->nextTokenKind() != TokenInfo::TK_Period) {
34840797Sbrian        *Value = NamedValue;
34936285Sbrian        return true;
35036285Sbrian      }
35140797Sbrian
35240797Sbrian      std::string BindID;
35340797Sbrian      if (!parseBindID(BindID))
35436285Sbrian        return false;
35540797Sbrian
35626516Sbrian      assert(NamedValue.isMatcher());
3576059Samurai      llvm::Optional<DynTypedMatcher> Result =
3586059Samurai          NamedValue.getMatcher().getSingleMatcher();
35985991Sbrian      if (Result.hasValue()) {
36085991Sbrian        llvm::Optional<DynTypedMatcher> Bound = Result->tryBind(BindID);
36185991Sbrian        if (Bound.hasValue()) {
36285991Sbrian          *Value = VariantMatcher::SingleMatcher(*Bound);
36385991Sbrian          return true;
36485991Sbrian        }
36585991Sbrian      }
36685991Sbrian      return false;
36785991Sbrian    }
368134789Sbrian    // If the syntax is correct and the name is not a matcher either, report
36985991Sbrian    // unknown named value.
37085991Sbrian    if ((Tokenizer->nextTokenKind() == TokenInfo::TK_Comma ||
37185991Sbrian         Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen ||
37286760Sbrian         Tokenizer->nextTokenKind() == TokenInfo::TK_Eof) &&
37385991Sbrian        !S->lookupMatcherCtor(NameToken.Text)) {
37485991Sbrian      Error->addError(NameToken.Range, Error->ET_RegistryValueNotFound)
37585991Sbrian          << NameToken.Text;
37685991Sbrian      return false;
37785991Sbrian    }
37885991Sbrian    // Otherwise, fallback to the matcher parser.
37985991Sbrian  }
38085991Sbrian
38185991Sbrian  // Parse as a matcher expression.
38285991Sbrian  return parseMatcherExpressionImpl(NameToken, Value);
383134789Sbrian}
38436285Sbrian
38585991Sbrianbool Parser::parseBindID(std::string &BindID) {
38636285Sbrian  // Parse .bind("foo")
38736285Sbrian  assert(Tokenizer->peekNextToken().Kind == TokenInfo::TK_Period);
38836285Sbrian  Tokenizer->consumeNextToken(); // consume the period.
38910528Samurai  const TokenInfo BindToken = Tokenizer->consumeNextToken();
39036285Sbrian  if (BindToken.Kind == TokenInfo::TK_CodeCompletion) {
39128536Sbrian    addCompletion(BindToken, MatcherCompletion("bind(\"", "bind", 1));
39236285Sbrian    return false;
39336285Sbrian  }
39436465Sbrian
39536465Sbrian  const TokenInfo OpenToken = Tokenizer->consumeNextToken();
39636928Sbrian  const TokenInfo IDToken = Tokenizer->consumeNextToken();
39736285Sbrian  const TokenInfo CloseToken = Tokenizer->consumeNextToken();
39836285Sbrian
39936285Sbrian  // TODO: We could use different error codes for each/some to be more
40034536Sbrian  //       explicit about the syntax error.
40136285Sbrian  if (BindToken.Kind != TokenInfo::TK_Ident ||
40236285Sbrian      BindToken.Text != TokenInfo::ID_Bind) {
40336285Sbrian    Error->addError(BindToken.Range, Error->ET_ParserMalformedBindExpr);
40436285Sbrian    return false;
40537993Sbrian  }
40636285Sbrian  if (OpenToken.Kind != TokenInfo::TK_OpenParen) {
40736285Sbrian    Error->addError(OpenToken.Range, Error->ET_ParserMalformedBindExpr);
40828536Sbrian    return false;
40928536Sbrian  }
41038628Sbrian  if (IDToken.Kind != TokenInfo::TK_Literal || !IDToken.Value.isString()) {
41138628Sbrian    Error->addError(IDToken.Range, Error->ET_ParserMalformedBindExpr);
41238628Sbrian    return false;
41338628Sbrian  }
41438628Sbrian  if (CloseToken.Kind != TokenInfo::TK_CloseParen) {
41538628Sbrian    Error->addError(CloseToken.Range, Error->ET_ParserMalformedBindExpr);
41638628Sbrian    return false;
41738628Sbrian  }
41838628Sbrian  BindID = IDToken.Value.getString();
41938628Sbrian  return true;
42038628Sbrian}
42138628Sbrian
42238628Sbrian/// Parse and validate a matcher expression.
42347865Sbrian/// \return \c true on success, in which case \c Value has the matcher parsed.
42447865Sbrian///   If the input is malformed, or some argument has an error, it
42547865Sbrian///   returns \c false.
42647865Sbrianbool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken,
42747865Sbrian                                        VariantValue *Value) {
42838628Sbrian  assert(NameToken.Kind == TokenInfo::TK_Ident);
42938628Sbrian  const TokenInfo OpenToken = Tokenizer->consumeNextToken();
43038628Sbrian  if (OpenToken.Kind != TokenInfo::TK_OpenParen) {
43138628Sbrian    Error->addError(OpenToken.Range, Error->ET_ParserNoOpenParen)
43238628Sbrian        << OpenToken.Text;
43338628Sbrian    return false;
43438628Sbrian  }
43538628Sbrian
43638628Sbrian  llvm::Optional<MatcherCtor> Ctor = S->lookupMatcherCtor(NameToken.Text);
43738628Sbrian
43838628Sbrian  if (!Ctor) {
43938628Sbrian    Error->addError(NameToken.Range, Error->ET_RegistryMatcherNotFound)
44038628Sbrian        << NameToken.Text;
44138628Sbrian    // Do not return here. We need to continue to give completion suggestions.
44238628Sbrian  }
44338628Sbrian
44438628Sbrian  std::vector<ParserValue> Args;
44538628Sbrian  TokenInfo EndToken;
44638628Sbrian
44738628Sbrian  {
44838628Sbrian    ScopedContextEntry SCE(this, Ctor ? *Ctor : nullptr);
44938628Sbrian
45038628Sbrian    while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) {
45138628Sbrian      if (Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen) {
45238628Sbrian        // End of args.
45338628Sbrian        EndToken = Tokenizer->consumeNextToken();
45438628Sbrian        break;
45538628Sbrian      }
45638628Sbrian      if (!Args.empty()) {
45738628Sbrian        // We must find a , token to continue.
458141504Sbrian        const TokenInfo CommaToken = Tokenizer->consumeNextToken();
45938628Sbrian        if (CommaToken.Kind != TokenInfo::TK_Comma) {
46038628Sbrian          Error->addError(CommaToken.Range, Error->ET_ParserNoComma)
46138628Sbrian              << CommaToken.Text;
46238628Sbrian          return false;
46338628Sbrian        }
46438628Sbrian      }
46594934Sbrian
46694934Sbrian      Diagnostics::Context Ctx(Diagnostics::Context::MatcherArg, Error,
46794934Sbrian                               NameToken.Text, NameToken.Range,
46894934Sbrian                               Args.size() + 1);
46994934Sbrian      ParserValue ArgValue;
47094934Sbrian      ArgValue.Text = Tokenizer->peekNextToken().Text;
47194934Sbrian      ArgValue.Range = Tokenizer->peekNextToken().Range;
47297360Sbrian      if (!parseExpressionImpl(&ArgValue.Value)) {
47394934Sbrian        return false;
47497360Sbrian      }
47594934Sbrian
47697360Sbrian      Args.push_back(ArgValue);
47794934Sbrian      SCE.nextArg();
47894934Sbrian    }
47994934Sbrian  }
48094934Sbrian
48194934Sbrian  if (EndToken.Kind == TokenInfo::TK_Eof) {
48294934Sbrian    Error->addError(OpenToken.Range, Error->ET_ParserNoCloseParen);
48394934Sbrian    return false;
48494934Sbrian  }
48594934Sbrian
48694934Sbrian  std::string BindID;
48794934Sbrian  if (Tokenizer->peekNextToken().Kind == TokenInfo::TK_Period) {
48894934Sbrian    if (!parseBindID(BindID))
48994934Sbrian      return false;
49094934Sbrian  }
49194934Sbrian
49294934Sbrian  if (!Ctor)
49394934Sbrian    return false;
49494934Sbrian
49594934Sbrian  // Merge the start and end infos.
49694934Sbrian  Diagnostics::Context Ctx(Diagnostics::Context::ConstructMatcher, Error,
49794934Sbrian                           NameToken.Text, NameToken.Range);
498116622Sume  SourceRange MatcherRange = NameToken.Range;
499116622Sume  MatcherRange.End = EndToken.Range.End;
500116622Sume  VariantMatcher Result = S->actOnMatcherExpression(
501116622Sume      *Ctor, MatcherRange, BindID, Args, Error);
502116622Sume  if (Result.isNull()) return false;
503116622Sume
504116622Sume  *Value = Result;
505116622Sume  return true;
506116622Sume}
507116622Sume
508116622Sume// If the prefix of this completion matches the completion token, add it to
509116622Sume// Completions minus the prefix.
510116622Sumevoid Parser::addCompletion(const TokenInfo &CompToken,
511116622Sume                           const MatcherCompletion& Completion) {
512116622Sume  if (StringRef(Completion.TypedText).startswith(CompToken.Text) &&
51394934Sbrian      Completion.Specificity > 0) {
514116622Sume    Completions.emplace_back(Completion.TypedText.substr(CompToken.Text.size()),
51594934Sbrian                             Completion.MatcherDecl, Completion.Specificity);
51643888Sbrian  }
51743888Sbrian}
51847849Sbrian
51938628Sbrianstd::vector<MatcherCompletion> Parser::getNamedValueCompletions(
52085991Sbrian    ArrayRef<ArgKind> AcceptedTypes) {
52194934Sbrian  if (!NamedValues) return std::vector<MatcherCompletion>();
52294934Sbrian  std::vector<MatcherCompletion> Result;
52338628Sbrian  for (const auto &Entry : *NamedValues) {
52441755Sbrian    unsigned Specificity;
52541755Sbrian    if (Entry.getValue().isConvertibleTo(AcceptedTypes, &Specificity)) {
52641755Sbrian      std::string Decl =
52741755Sbrian          (Entry.getValue().getTypeAsString() + " " + Entry.getKey()).str();
52841755Sbrian      Result.emplace_back(Entry.getKey(), Decl, Specificity);
52941755Sbrian    }
53094934Sbrian  }
53194934Sbrian  return Result;
53294934Sbrian}
53394934Sbrian
53494934Sbrianvoid Parser::addExpressionCompletions() {
53594934Sbrian  const TokenInfo CompToken = Tokenizer->consumeNextToken();
53694934Sbrian  assert(CompToken.Kind == TokenInfo::TK_CodeCompletion);
53794934Sbrian
53894934Sbrian  // We cannot complete code if there is an invalid element on the context
53994934Sbrian  // stack.
54094934Sbrian  for (ContextStackTy::iterator I = ContextStack.begin(),
54194934Sbrian                                E = ContextStack.end();
54294934Sbrian       I != E; ++I) {
54394934Sbrian    if (!I->first)
54494934Sbrian      return;
54541755Sbrian  }
54638629Sbrian
54794934Sbrian  auto AcceptedTypes = S->getAcceptedCompletionTypes(ContextStack);
54894934Sbrian  for (const auto &Completion : S->getMatcherCompletions(AcceptedTypes)) {
54994934Sbrian    addCompletion(CompToken, Completion);
55094934Sbrian  }
55198243Sbrian
55294934Sbrian  for (const auto &Completion : getNamedValueCompletions(AcceptedTypes)) {
55394934Sbrian    addCompletion(CompToken, Completion);
55494934Sbrian  }
55594934Sbrian}
55681634Sbrian
55794934Sbrian/// Parse an <Expression>
55881634Sbrianbool Parser::parseExpressionImpl(VariantValue *Value) {
55940561Sbrian  switch (Tokenizer->nextTokenKind()) {
56094934Sbrian  case TokenInfo::TK_Literal:
56194934Sbrian    *Value = Tokenizer->consumeNextToken().Value;
56298243Sbrian    return true;
56394934Sbrian
56498243Sbrian  case TokenInfo::TK_Ident:
56594934Sbrian    return parseIdentifierPrefixImpl(Value);
56698243Sbrian
56794934Sbrian  case TokenInfo::TK_CodeCompletion:
56881634Sbrian    addExpressionCompletions();
56998243Sbrian    return false;
57094934Sbrian
57198243Sbrian  case TokenInfo::TK_Eof:
57294934Sbrian    Error->addError(Tokenizer->consumeNextToken().Range,
57398243Sbrian                    Error->ET_ParserNoCode);
57494934Sbrian    return false;
57598243Sbrian
57694934Sbrian  case TokenInfo::TK_Error:
57781634Sbrian    // This error was already reported by the tokenizer.
57894934Sbrian    return false;
57994934Sbrian
58094934Sbrian  case TokenInfo::TK_OpenParen:
58194934Sbrian  case TokenInfo::TK_CloseParen:
582116622Sume  case TokenInfo::TK_Comma:
583116622Sume  case TokenInfo::TK_Period:
584116622Sume  case TokenInfo::TK_InvalidChar:
58594934Sbrian    const TokenInfo Token = Tokenizer->consumeNextToken();
586116622Sume    Error->addError(Token.Range, Error->ET_ParserInvalidToken) << Token.Text;
58794934Sbrian    return false;
58894934Sbrian  }
58994934Sbrian
59094934Sbrian  llvm_unreachable("Unknown token kind.");
59138629Sbrian}
59238629Sbrian
59338629Sbrianstatic llvm::ManagedStatic<Parser::RegistrySema> DefaultRegistrySema;
59438629Sbrian
59597360SbrianParser::Parser(CodeTokenizer *Tokenizer, Sema *S,
59694934Sbrian               const NamedValueMap *NamedValues, Diagnostics *Error)
59797360Sbrian    : Tokenizer(Tokenizer), S(S ? S : &*DefaultRegistrySema),
59894934Sbrian      NamedValues(NamedValues), Error(Error) {}
59994934Sbrian
60094934SbrianParser::RegistrySema::~RegistrySema() = default;
60194934Sbrian
60263484Sbrianllvm::Optional<MatcherCtor>
60338628SbrianParser::RegistrySema::lookupMatcherCtor(StringRef MatcherName) {
60438628Sbrian  return Registry::lookupMatcherCtor(MatcherName);
60538628Sbrian}
60638628Sbrian
60785991SbrianVariantMatcher Parser::RegistrySema::actOnMatcherExpression(
60885991Sbrian    MatcherCtor Ctor, SourceRange NameRange, StringRef BindID,
60985991Sbrian    ArrayRef<ParserValue> Args, Diagnostics *Error) {
61085991Sbrian  if (BindID.empty()) {
61185991Sbrian    return Registry::constructMatcher(Ctor, NameRange, Args, Error);
61285991Sbrian  } else {
61385991Sbrian    return Registry::constructBoundMatcher(Ctor, NameRange, BindID, Args,
61485991Sbrian                                           Error);
61585991Sbrian  }
61685991Sbrian}
61728536Sbrian
61831343Sbrianstd::vector<ArgKind> Parser::RegistrySema::getAcceptedCompletionTypes(
61910528Samurai    ArrayRef<std::pair<MatcherCtor, unsigned>> Context) {
62010528Samurai  return Registry::getAcceptedCompletionTypes(Context);
62147849Sbrian}
62220813Sjkh
62318856Ssosstd::vector<MatcherCompletion> Parser::RegistrySema::getMatcherCompletions(
62426911Sbrian    ArrayRef<ArgKind> AcceptedTypes) {
62536285Sbrian  return Registry::getMatcherCompletions(AcceptedTypes);
62636285Sbrian}
62726516Sbrian
62810528Samuraibool Parser::parseExpression(StringRef Code, Sema *S,
62926911Sbrian                             const NamedValueMap *NamedValues,
63028679Sbrian                             VariantValue *Value, Diagnostics *Error) {
63136285Sbrian  CodeTokenizer Tokenizer(Code, Error);
63236285Sbrian  if (!Parser(&Tokenizer, S, NamedValues, Error).parseExpressionImpl(Value))
63336285Sbrian    return false;
63436285Sbrian  if (Tokenizer.peekNextToken().Kind != TokenInfo::TK_Eof) {
63528381Sbrian    Error->addError(Tokenizer.peekNextToken().Range,
63636285Sbrian                    Error->ET_ParserTrailingCode);
63736285Sbrian    return false;
63836285Sbrian  }
63936285Sbrian  return true;
64028381Sbrian}
64136285Sbrian
64228679Sbrianstd::vector<MatcherCompletion>
64328381SbrianParser::completeExpression(StringRef Code, unsigned CompletionOffset, Sema *S,
64428381Sbrian                           const NamedValueMap *NamedValues) {
64534536Sbrian  Diagnostics Error;
64634536Sbrian  CodeTokenizer Tokenizer(Code, &Error, CompletionOffset);
64747849Sbrian  Parser P(&Tokenizer, S, NamedValues, &Error);
64828679Sbrian  VariantValue Dummy;
64936285Sbrian  P.parseExpressionImpl(&Dummy);
65018531Sbde
65136285Sbrian  // Sort by specificity, then by name.
65236285Sbrian  llvm::sort(P.Completions,
65332017Sbrian             [](const MatcherCompletion &A, const MatcherCompletion &B) {
65436285Sbrian               if (A.Specificity != B.Specificity)
65536285Sbrian                 return A.Specificity > B.Specificity;
65636285Sbrian               return A.TypedText < B.TypedText;
65736285Sbrian             });
65836285Sbrian
65936285Sbrian  return P.Completions;
66036285Sbrian}
66128679Sbrian
66228679Sbrianllvm::Optional<DynTypedMatcher>
66349976SbrianParser::parseMatcherExpression(StringRef Code, Sema *S,
66449976Sbrian                               const NamedValueMap *NamedValues,
66549976Sbrian                               Diagnostics *Error) {
66649976Sbrian  VariantValue Value;
66749976Sbrian  if (!parseExpression(Code, S, NamedValues, &Value, Error))
66826516Sbrian    return llvm::Optional<DynTypedMatcher>();
66964802Sbrian  if (!Value.isMatcher()) {
67055252Sbrian    Error->addError(SourceRange(), Error->ET_ParserNotAMatcher);
67164802Sbrian    return llvm::Optional<DynTypedMatcher>();
67236285Sbrian  }
67328679Sbrian  llvm::Optional<DynTypedMatcher> Result =
67438628Sbrian      Value.getMatcher().getSingleMatcher();
67538628Sbrian  if (!Result.hasValue()) {
67638628Sbrian    Error->addError(SourceRange(), Error->ET_ParserOverloadedType)
677134789Sbrian        << Value.getTypeAsString();
67838628Sbrian  }
67938628Sbrian  return Result;
68031343Sbrian}
68147849Sbrian
68228679Sbrian} // namespace dynamic
68328679Sbrian} // namespace ast_matchers
68410528Samurai} // namespace clang
68528679Sbrian