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