本文整理汇总了C++中ParserResult类的典型用法代码示例。如果您正苦于以下问题:C++ ParserResult类的具体用法?C++ ParserResult怎么用?C++ ParserResult使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了ParserResult类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: assert
bool Parser::parseGenericArguments(SmallVectorImpl<TypeRepr*> &Args,
SourceLoc &LAngleLoc,
SourceLoc &RAngleLoc) {
// Parse the opening '<'.
assert(startsWithLess(Tok) && "Generic parameter list must start with '<'");
LAngleLoc = consumeStartingLess();
do {
ParserResult<TypeRepr> Ty = parseType(diag::expected_type);
if (Ty.isNull() || Ty.hasCodeCompletion()) {
// Skip until we hit the '>'.
RAngleLoc = skipUntilGreaterInTypeList();
return true;
}
Args.push_back(Ty.get());
// Parse the comma, if the list continues.
} while (consumeIf(tok::comma));
if (!startsWithGreater(Tok)) {
checkForInputIncomplete();
diagnose(Tok, diag::expected_rangle_generic_arg_list);
diagnose(LAngleLoc, diag::opening_angle);
// Skip until we hit the '>'.
RAngleLoc = skipUntilGreaterInTypeList();
return true;
} else {
RAngleLoc = consumeStartingGreater();
}
return false;
}
示例2: parseOptionalPatternTypeAnnotation
/// Parse an optional type annotation on a pattern.
///
/// pattern-type-annotation ::= (':' type)?
///
ParserResult<Pattern> Parser::
parseOptionalPatternTypeAnnotation(ParserResult<Pattern> result,
bool isOptional) {
// Parse an optional type annotation.
if (!consumeIf(tok::colon))
return result;
Pattern *P;
if (result.isNull()) // Recover by creating AnyPattern.
P = new (Context) AnyPattern(Tok.getLoc());
else
P = result.get();
ParserResult<TypeRepr> Ty = parseType();
if (Ty.hasCodeCompletion())
return makeParserCodeCompletionResult<Pattern>();
TypeRepr *repr = Ty.getPtrOrNull();
if (!repr)
repr = new (Context) ErrorTypeRepr(PreviousLoc);
// In an if-let, the actual type of the expression is Optional of whatever
// was written.
if (isOptional)
repr = new (Context) OptionalTypeRepr(repr, Tok.getLoc());
return makeParserResult(new (Context) TypedPattern(P, repr));
}
示例3: parsePattern
/// Parse a pattern with an optional type annotation.
///
/// typed-pattern ::= pattern (':' type)?
///
ParserResult<Pattern> Parser::parseTypedPattern() {
auto result = parsePattern();
// Now parse an optional type annotation.
if (Tok.is(tok::colon)) {
SourceLoc colonLoc = consumeToken(tok::colon);
if (result.isNull()) // Recover by creating AnyPattern.
result = makeParserErrorResult(new (Context) AnyPattern(colonLoc));
ParserResult<TypeRepr> Ty = parseType();
if (Ty.hasCodeCompletion())
return makeParserCodeCompletionResult<Pattern>();
if (!Ty.isNull()) {
// Attempt to diagnose initializer calls incorrectly written
// as typed patterns, such as "var x: [Int]()".
if (Tok.isFollowingLParen()) {
BacktrackingScope backtrack(*this);
// Create a local context if needed so we can parse trailing closures.
LocalContext dummyContext;
Optional<ContextChange> contextChange;
if (!CurLocalContext) {
contextChange.emplace(*this, CurDeclContext, &dummyContext);
}
SourceLoc lParenLoc, rParenLoc;
SmallVector<Expr *, 2> args;
SmallVector<Identifier, 2> argLabels;
SmallVector<SourceLoc, 2> argLabelLocs;
Expr *trailingClosure;
ParserStatus status = parseExprList(tok::l_paren, tok::r_paren,
/*isPostfix=*/true,
/*isExprBasic=*/false,
lParenLoc, args, argLabels,
argLabelLocs, rParenLoc,
trailingClosure);
if (status.isSuccess()) {
backtrack.cancelBacktrack();
// Suggest replacing ':' with '='
diagnose(lParenLoc, diag::initializer_as_typed_pattern)
.highlight({Ty.get()->getStartLoc(), rParenLoc})
.fixItReplace(colonLoc, " = ");
result.setIsParseError();
}
}
} else {
Ty = makeParserResult(new (Context) ErrorTypeRepr(PreviousLoc));
}
result = makeParserResult(result,
new (Context) TypedPattern(result.get(), Ty.get()));
}
return result;
}
示例4: void
bool SceneGraph::add(const char *filename, bool bInitialize, void (*callbackFn)(int nLine, void *info), void *callbackFnInfo)
{
int fileFormat = GetFileFormat(filename);
Parser *parser = NULL;
ParserResult *presult = getParserResult();
presult->init();
presult->setParserResult(false);
switch (fileFormat) {
case FILE_FORMAT_VRML:
parser = new VRML97Parser();
break;
#ifdef CX3D_SUPPORT_X3D
case FILE_FORMAT_XML:
parser = new X3DParser();
break;
#endif
#ifdef CX3D_SUPPORT_OBJ
case FILE_FORMAT_OBJ:
parser = new OBJParser();
break;
#endif
}
if (parser == NULL)
return false;
SetParserResultObject(presult);
bool parserRet = parser->load(filename, callbackFn, callbackFnInfo);
presult->setParserResult(parserRet);
if (parserRet == false) {
delete parser;
return false;
}
moveParserNodes(parser);
moveParserRoutes(parser);
delete parser;
if (bInitialize)
initialize();
setBackgroundNode(findBackgroundNode(), true);
setFogNode(findFogNode(), true);
setNavigationInfoNode(findNavigationInfoNode(), true);
setViewpointNode(findViewpointNode(), true);
return true;
}
示例5: consumeToken
/// parseTypeComposition
///
/// type-composition:
/// 'protocol' '<' type-composition-list? '>'
///
/// type-composition-list:
/// type-identifier (',' type-identifier)*
///
ParserResult<ProtocolCompositionTypeRepr> Parser::parseTypeComposition() {
SourceLoc ProtocolLoc = consumeToken(tok::kw_protocol);
// Check for the starting '<'.
if (!startsWithLess(Tok)) {
diagnose(Tok, diag::expected_langle_protocol);
return nullptr;
}
SourceLoc LAngleLoc = consumeStartingLess();
// Check for empty protocol composition.
if (startsWithGreater(Tok)) {
SourceLoc RAngleLoc = consumeStartingGreater();
return makeParserResult(new (Context) ProtocolCompositionTypeRepr(
ArrayRef<IdentTypeRepr *>(),
ProtocolLoc,
SourceRange(LAngleLoc,
RAngleLoc)));
}
// Parse the type-composition-list.
ParserStatus Status;
SmallVector<IdentTypeRepr *, 4> Protocols;
do {
// Parse the type-identifier.
ParserResult<IdentTypeRepr> Protocol = parseTypeIdentifier();
Status |= Protocol;
if (Protocol.isNonNull())
Protocols.push_back(Protocol.get());
} while (consumeIf(tok::comma));
// Check for the terminating '>'.
SourceLoc EndLoc = PreviousLoc;
if (startsWithGreater(Tok)) {
EndLoc = consumeStartingGreater();
} else {
if (Status.isSuccess()) {
diagnose(Tok, diag::expected_rangle_protocol);
diagnose(LAngleLoc, diag::opening_angle);
Status.setIsParseError();
}
// Skip until we hit the '>'.
EndLoc = skipUntilGreaterInTypeList(/*protocolComposition=*/true);
}
return makeParserResult(Status, ProtocolCompositionTypeRepr::create(
Context, Protocols, ProtocolLoc, SourceRange(LAngleLoc, EndLoc)));
}
示例6: tmpfile
SAWYER_EXPORT std::string
PodFormatter::toNroff(const ParserResult &parsed) {
// Generate POD documentation into a temporary file
TempFile tmpfile(tempFileName(".pod"));
parsed.emit(tmpfile.stream, sharedFromThis());
tmpfile.stream.close();
std::string cmd = "pod2man"
" --center='" + escapeSingleQuoted(chapterName_) + "'"
" --date='" + escapeSingleQuoted(dateString_) + "'"
" --name='" + escapeSingleQuoted(pageName_) + "'"
" --release='" + escapeSingleQuoted(versionString_) + "'"
" --section='" + escapeSingleQuoted(chapterNumber_) + "'"
" " + tmpfile.name;
FILE *f = popen(cmd.c_str(), "r");
if (!f) {
#include <Sawyer/WarningsOff.h> // suppress strerror unsafe warning from Microsoft C++
throw std::runtime_error(std::string("cannot run command: ") + strerror(errno) + "\ncommand: " + cmd);
#include <Sawyer/WarningsRestore.h>
}
std::string result;
while (1) {
std::string line = readOneLine(f);
if (line.empty())
break;
result += line;
}
if (-1 == Sawyer::pclose(f))
throw std::runtime_error("command failed: " + cmd);
return result;
}
示例7: parsePattern
/// Parse a pattern with an optional type annotation.
///
/// typed-pattern ::= pattern (':' type)?
///
ParserResult<Pattern> Parser::parseTypedPattern() {
auto result = parsePattern();
// Now parse an optional type annotation.
if (consumeIf(tok::colon)) {
if (result.isNull()) // Recover by creating AnyPattern.
result = makeParserErrorResult(new (Context) AnyPattern(PreviousLoc));
ParserResult<TypeRepr> Ty = parseType();
if (Ty.hasCodeCompletion())
return makeParserCodeCompletionResult<Pattern>();
if (Ty.isNull())
Ty = makeParserResult(new (Context) ErrorTypeRepr(PreviousLoc));
result = makeParserResult(result,
new (Context) TypedPattern(result.get(), Ty.get()));
}
return result;
}
示例8: consumeIdentifier
/// Parse an element of a tuple pattern.
///
/// pattern-tuple-element:
/// (identifier ':')? pattern
std::pair<ParserStatus, Optional<TuplePatternElt>>
Parser::parsePatternTupleElement() {
// If this element has a label, parse it.
Identifier Label;
SourceLoc LabelLoc;
// If the tuple element has a label, parse it.
if (Tok.is(tok::identifier) && peekToken().is(tok::colon)) {
LabelLoc = consumeIdentifier(&Label);
consumeToken(tok::colon);
}
// Parse the pattern.
ParserResult<Pattern> pattern = parsePattern();
if (pattern.hasCodeCompletion())
return std::make_pair(makeParserCodeCompletionStatus(), None);
if (pattern.isNull())
return std::make_pair(makeParserError(), None);
auto Elt = TuplePatternElt(Label, LabelLoc, pattern.get());
return std::make_pair(makeParserSuccess(), Elt);
}
示例9: diagnose
ParserResult<Pattern> Parser::parseMatchingPatternAsLetOrVar(bool isLet,
SourceLoc varLoc,
bool isExprBasic) {
// 'var' and 'let' patterns shouldn't nest.
if (InVarOrLetPattern == IVOLP_InLet ||
InVarOrLetPattern == IVOLP_InVar)
diagnose(varLoc, diag::var_pattern_in_var, unsigned(isLet));
// 'let' isn't valid inside an implicitly immutable context, but var is.
if (isLet && InVarOrLetPattern == IVOLP_ImplicitlyImmutable)
diagnose(varLoc, diag::let_pattern_in_immutable_context);
// In our recursive parse, remember that we're in a var/let pattern.
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
T(InVarOrLetPattern, isLet ? IVOLP_InLet : IVOLP_InVar);
ParserResult<Pattern> subPattern = parseMatchingPattern(isExprBasic);
if (subPattern.isNull())
return nullptr;
auto *varP = new (Context) VarPattern(varLoc, isLet, subPattern.get());
return makeParserResult(varP);
}
示例10: assert
/// matching-pattern ::= 'is' type
/// matching-pattern ::= matching-pattern-var
/// matching-pattern ::= expr
///
ParserResult<Pattern> Parser::parseMatchingPattern(bool isExprBasic) {
// TODO: Since we expect a pattern in this position, we should optimistically
// parse pattern nodes for productions shared by pattern and expression
// grammar. For short-term ease of initial implementation, we always go
// through the expr parser for ambiguous productions.
// Parse productions that can only be patterns.
if (Tok.isAny(tok::kw_var, tok::kw_let)) {
assert(Tok.isAny(tok::kw_let, tok::kw_var) && "expects var or let");
bool isLet = Tok.is(tok::kw_let);
SourceLoc varLoc = consumeToken();
return parseMatchingPatternAsLetOrVar(isLet, varLoc, isExprBasic);
}
// matching-pattern ::= 'is' type
if (Tok.is(tok::kw_is)) {
SourceLoc isLoc = consumeToken(tok::kw_is);
ParserResult<TypeRepr> castType = parseType();
if (castType.isNull() || castType.hasCodeCompletion())
return nullptr;
return makeParserResult(new (Context) IsPattern(isLoc, castType.get(),
nullptr));
}
// matching-pattern ::= expr
// Fall back to expression parsing for ambiguous forms. Name lookup will
// disambiguate.
ParserResult<Expr> subExpr =
parseExprImpl(diag::expected_pattern, isExprBasic);
if (subExpr.hasCodeCompletion())
return makeParserCodeCompletionStatus();
if (subExpr.isNull())
return nullptr;
// The most common case here is to parse something that was a lexically
// obvious pattern, which will come back wrapped in an immediate
// UnresolvedPatternExpr. Transform this now to simplify later code.
if (auto *UPE = dyn_cast<UnresolvedPatternExpr>(subExpr.get()))
return makeParserResult(UPE->getSubPattern());
return makeParserResult(new (Context) ExprPattern(subExpr.get()));
}
示例11: parse
ParserResult Parser::parse(string input){
vector<string> output;
ParserResult parserResult;
try {
string userInput = input;
LOG(INFO) << "Parser-Initial input:" << userInput;
if (userInput.empty()) {
resetAll();
throw std::out_of_range(ERROR_EMPTY_INPUT);
}
userInput = removeExtraSpacePadding(userInput);
setCommand(userInput);
LOG(INFO) << "Parser-After setCommand:" << userInput;
setDateAndTime(userInput);
LOG(INFO) << "Parser-After setDateAndTime:" << userInput;
setIndex(userInput);
LOG(INFO) << "Parser-After setIndex:" << userInput;
setDescription(userInput);
LOG(INFO) << "Parser-After setDescription:" << userInput;
}
catch (const out_of_range& error) {
LOG(INFO) << "Parser-Exception:" << error.what();
resetAll();
throw std::out_of_range(error.what());
}
parserResult.setUserCommand(_userCommand);
parserResult.setDescription(_description);
parserResult.setIndex(_index);
parserResult.setEntryType(_entryType);
parserResult.setStartDate(_startYear, _startMonth, _startDay);
parserResult.setStartTime(_startTime);
parserResult.setEndDate(_endYear, _endMonth, _endDay);
parserResult.setEndTime(_endTime);
resetAll();
return parserResult;
}
示例12: tmpdir
SAWYER_EXPORT void
PodFormatter::emit(const ParserResult &parsed) {
// Generate POD documentation into a temporary file. Since perldoc doesn't support the "name" property, but rather
// uses the file name, we create a temporary directory and place a POD file inside with the name we want.
TempDir tmpdir(tempFileName());
std::string fileName = tmpdir.name + pageName_ + ".pod";
{
std::ofstream stream(fileName.c_str());
parsed.emit(stream, sharedFromThis());
}
std::string cmd = "perldoc "
" -o man"
" -w 'center:" + escapeSingleQuoted(chapterName_) + "'"
" -w 'date:" + escapeSingleQuoted(dateString_) + "'"
// " -w 'name:" + escapeSingleQuoted(pageName_) + "'"
" -w 'release:" + escapeSingleQuoted(versionString_) + "'"
" -w 'section:" + escapeSingleQuoted(chapterNumber_) + "'"
" " + fileName;
system(cmd.c_str());
}
示例13: ParsingTypeTuple
/// parseTypeTupleBody
/// type-tuple:
/// '(' type-tuple-body? ')'
/// type-tuple-body:
/// type-tuple-element (',' type-tuple-element)* '...'?
/// type-tuple-element:
/// identifier ':' type
/// type
ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
Parser::StructureMarkerRAII ParsingTypeTuple(*this, Tok);
SourceLoc RPLoc, LPLoc = consumeToken(tok::l_paren);
SourceLoc EllipsisLoc;
unsigned EllipsisIdx;
SmallVector<TypeRepr *, 8> ElementsR;
// We keep track of the labels separately, and apply them at the end.
SmallVector<std::tuple<Identifier, SourceLoc, Identifier, SourceLoc>, 4>
Labels;
ParserStatus Status = parseList(tok::r_paren, LPLoc, RPLoc,
tok::comma, /*OptionalSep=*/false,
/*AllowSepAfterLast=*/false,
diag::expected_rparen_tuple_type_list,
[&] () -> ParserStatus {
// If this is a deprecated use of the inout marker in an argument list,
// consume the inout.
SourceLoc InOutLoc;
bool hasAnyInOut = false;
bool hasValidInOut = false;
if (consumeIf(tok::kw_inout, InOutLoc)) {
hasAnyInOut = true;
hasValidInOut = false;
}
// If the tuple element starts with a potential argument label followed by a
// ':' or another potential argument label, then the identifier is an
// element tag, and it is followed by a type annotation.
if (Tok.canBeArgumentLabel() &&
(peekToken().is(tok::colon) || peekToken().canBeArgumentLabel())) {
// Consume the name
Identifier name;
if (!Tok.is(tok::kw__))
name = Context.getIdentifier(Tok.getText());
SourceLoc nameLoc = consumeToken();
// If there is a second name, consume it as well.
Identifier secondName;
SourceLoc secondNameLoc;
if (Tok.canBeArgumentLabel()) {
if (!Tok.is(tok::kw__))
secondName = Context.getIdentifier(Tok.getText());
secondNameLoc = consumeToken();
}
// Consume the ':'.
if (!consumeIf(tok::colon))
diagnose(Tok, diag::expected_parameter_colon);
SourceLoc postColonLoc = Tok.getLoc();
// Consume 'inout' if present.
if (!hasAnyInOut && consumeIf(tok::kw_inout, InOutLoc)) {
hasValidInOut = true;
}
SourceLoc extraneousInOutLoc;
while (consumeIf(tok::kw_inout, extraneousInOutLoc)) {
diagnose(Tok, diag::parameter_inout_var_let_repeated)
.fixItRemove(extraneousInOutLoc);
}
// Parse the type annotation.
ParserResult<TypeRepr> type = parseType(diag::expected_type);
if (type.hasCodeCompletion())
return makeParserCodeCompletionStatus();
if (type.isNull())
return makeParserError();
if (!hasValidInOut && hasAnyInOut) {
diagnose(Tok.getLoc(), diag::inout_as_attr_disallowed)
.fixItRemove(InOutLoc)
.fixItInsert(postColonLoc, "inout ");
}
// If an 'inout' marker was specified, build the type. Note that we bury
// the inout locator within the named locator. This is weird but required
// by sema apparently.
if (InOutLoc.isValid())
type = makeParserResult(new (Context) InOutTypeRepr(type.get(),
InOutLoc));
// Record the label. We will look at these at the end.
if (Labels.empty()) {
Labels.assign(ElementsR.size(),
std::make_tuple(Identifier(), SourceLoc(),
Identifier(), SourceLoc()));
}
Labels.push_back(std::make_tuple(name, nameLoc,
secondName, secondNameLoc));
ElementsR.push_back(type.get());
//.........这里部分代码省略.........
示例14: consumeIf
/// parseTypeSimple
/// type-simple:
/// type-identifier
/// type-tuple
/// type-composition
/// 'Any'
/// type-simple '.Type'
/// type-simple '.Protocol'
/// type-simple '?'
/// type-simple '!'
/// type-collection
ParserResult<TypeRepr> Parser::parseTypeSimple(Diag<> MessageID,
bool HandleCodeCompletion) {
ParserResult<TypeRepr> ty;
// If this is an "inout" marker for an identifier type, consume the inout.
SourceLoc InOutLoc;
consumeIf(tok::kw_inout, InOutLoc);
switch (Tok.getKind()) {
case tok::kw_Self:
ty = parseTypeIdentifier();
break;
case tok::identifier:
case tok::kw_protocol:
case tok::kw_Any:
ty = parseTypeIdentifierOrTypeComposition();
break;
case tok::l_paren:
ty = parseTypeTupleBody();
break;
case tok::code_complete:
if (!HandleCodeCompletion)
break;
if (CodeCompletion)
CodeCompletion->completeTypeSimpleBeginning();
// Eat the code completion token because we handled it.
consumeToken(tok::code_complete);
return makeParserCodeCompletionResult<TypeRepr>();
case tok::kw_super:
case tok::kw_self:
// These keywords don't start a decl or a statement, and thus should be
// safe to skip over.
diagnose(Tok, MessageID);
ty = makeParserErrorResult(new (Context) ErrorTypeRepr(Tok.getLoc()));
consumeToken();
// FIXME: we could try to continue to parse.
return ty;
case tok::l_square:
ty = parseTypeCollection();
break;
default:
checkForInputIncomplete();
diagnose(Tok, MessageID);
return nullptr;
}
// '.Type', '.Protocol', '?', and '!' still leave us with type-simple.
while (ty.isNonNull()) {
if ((Tok.is(tok::period) || Tok.is(tok::period_prefix))) {
if (peekToken().isContextualKeyword("Type")) {
consumeToken();
SourceLoc metatypeLoc = consumeToken(tok::identifier);
ty = makeParserResult(ty,
new (Context) MetatypeTypeRepr(ty.get(), metatypeLoc));
continue;
}
if (peekToken().isContextualKeyword("Protocol")) {
consumeToken();
SourceLoc protocolLoc = consumeToken(tok::identifier);
ty = makeParserResult(ty,
new (Context) ProtocolTypeRepr(ty.get(), protocolLoc));
continue;
}
}
if (!Tok.isAtStartOfLine()) {
if (isOptionalToken(Tok)) {
ty = parseTypeOptional(ty.get());
continue;
}
if (isImplicitlyUnwrappedOptionalToken(Tok)) {
ty = parseTypeImplicitlyUnwrappedOptional(ty.get());
continue;
}
}
break;
}
// If we parsed an inout modifier, prepend it.
if (InOutLoc.isValid())
ty = makeParserResult(new (Context) InOutTypeRepr(ty.get(),
InOutLoc));
return ty;
}
示例15: consumeToken
/// parseTypeIdentifierOrTypeComposition
/// - Identifiers and compositions both start with the same identifier
/// token, parse it and continue constructing a composition if the
/// next token is '&'
///
/// type-composition:
/// type-identifier ('&' type-identifier)*
/// 'protocol' '<' type-composition-list-deprecated? '>'
///
/// type-composition-list-deprecated:
/// type-identifier (',' type-identifier)*
ParserResult<TypeRepr> Parser::parseTypeIdentifierOrTypeComposition() {
// Handle deprecated case
if (Tok.getKind() == tok::kw_protocol && startsWithLess(peekToken())) {
SourceLoc ProtocolLoc = consumeToken(tok::kw_protocol);
SourceLoc LAngleLoc = consumeStartingLess();
// Parse the type-composition-list.
ParserStatus Status;
SmallVector<IdentTypeRepr *, 4> Protocols;
bool IsEmpty = startsWithGreater(Tok);
if (!IsEmpty) {
do {
// Parse the type-identifier.
ParserResult<TypeRepr> Protocol = parseTypeIdentifier();
Status |= Protocol;
if (auto *ident = dyn_cast_or_null<IdentTypeRepr>(
Protocol.getPtrOrNull()))
Protocols.push_back(ident);
} while (consumeIf(tok::comma));
}
// Check for the terminating '>'.
SourceLoc RAngleLoc = PreviousLoc;
if (startsWithGreater(Tok)) {
RAngleLoc = consumeStartingGreater();
} else {
if (Status.isSuccess()) {
diagnose(Tok, diag::expected_rangle_protocol);
diagnose(LAngleLoc, diag::opening_angle);
Status.setIsParseError();
}
// Skip until we hit the '>'.
RAngleLoc = skipUntilGreaterInTypeList(/*protocolComposition=*/true);
}
auto composition = ProtocolCompositionTypeRepr::create(
Context, Protocols, ProtocolLoc, {LAngleLoc, RAngleLoc});
if (Status.isSuccess()) {
// Only if we have complete protocol<...> construct, diagnose deprecated.
SmallString<32> replacement;
if (Protocols.empty()) {
replacement = "Any";
} else {
auto extractText = [&](IdentTypeRepr *Ty) -> StringRef {
auto SourceRange = Ty->getSourceRange();
return SourceMgr.extractText(
Lexer::getCharSourceRangeFromSourceRange(SourceMgr, SourceRange));
};
auto Begin = Protocols.begin();
replacement += extractText(*Begin);
while (++Begin != Protocols.end()) {
replacement += " & ";
replacement += extractText(*Begin);
}
}
// Copy trailing content after '>' to the replacement string.
// FIXME: lexer should smartly separate '>' and trailing contents like '?'.
StringRef TrailingContent = L->getTokenAt(RAngleLoc).getRange().str().
substr(1);
if (!TrailingContent.empty()) {
if (Protocols.size() > 1) {
replacement.insert(replacement.begin(), '(');
replacement += ")";
}
replacement += TrailingContent;
}
// Replace 'protocol<T1, T2>' with 'T1 & T2'
diagnose(ProtocolLoc,
IsEmpty ? diag::deprecated_any_composition :
Protocols.size() > 1 ? diag::deprecated_protocol_composition :
diag::deprecated_protocol_composition_single)
.highlight(composition->getSourceRange())
.fixItReplace(composition->getSourceRange(), replacement);
}
return makeParserResult(Status, composition);
}
SourceLoc FirstTypeLoc = Tok.getLoc();
// Parse the first type
ParserResult<TypeRepr> FirstType = parseTypeIdentifier();
if (!Tok.isContextualPunctuator("&"))
//.........这里部分代码省略.........