本文整理汇总了C++中ParserResult::isNull方法的典型用法代码示例。如果您正苦于以下问题:C++ ParserResult::isNull方法的具体用法?C++ ParserResult::isNull怎么用?C++ ParserResult::isNull使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ParserResult
的用法示例。
在下文中一共展示了ParserResult::isNull方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: parsingCollection
ParserResult<TypeRepr> Parser::parseTypeCollection() {
// Parse the leading '['.
assert(Tok.is(tok::l_square));
Parser::StructureMarkerRAII parsingCollection(*this, Tok);
SourceLoc lsquareLoc = consumeToken();
// Parse the element type.
ParserResult<TypeRepr> firstTy = parseType(diag::expected_element_type);
// If there is a ':', this is a dictionary type.
SourceLoc colonLoc;
ParserResult<TypeRepr> secondTy;
if (Tok.is(tok::colon)) {
colonLoc = consumeToken();
// Parse the second type.
secondTy = parseType(diag::expected_dictionary_value_type);
}
// Parse the closing ']'.
SourceLoc rsquareLoc;
parseMatchingToken(tok::r_square, rsquareLoc,
colonLoc.isValid()
? diag::expected_rbracket_dictionary_type
: diag::expected_rbracket_array_type,
lsquareLoc);
if (firstTy.hasCodeCompletion() || secondTy.hasCodeCompletion())
return makeParserCodeCompletionStatus();
// If we couldn't parse anything for one of the types, propagate the error.
if (firstTy.isNull() || (colonLoc.isValid() && secondTy.isNull()))
return makeParserError();
// Form the dictionary type.
SourceRange brackets(lsquareLoc, rsquareLoc);
if (colonLoc.isValid())
return makeParserResult(ParserStatus(firstTy) | ParserStatus(secondTy),
new (Context) DictionaryTypeRepr(firstTy.get(),
secondTy.get(),
colonLoc,
brackets));
// Form the array type.
return makeParserResult(firstTy,
new (Context) ArrayTypeRepr(firstTy.get(),
brackets));
}
示例2: makeParserResult
/// 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: parseGenericArguments
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;
}
示例4: backtrack
/// 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;
}
示例5: parseMatchingPatternAsLetOrVar
/// 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()));
}
示例6: parseType
ParserResult<TypeRepr> Parser::parseTypeIdentifierWithRecovery(
Diag<> MessageID, Diag<TypeLoc> NonIdentifierTypeMessageID) {
ParserResult<TypeRepr> Ty = parseType(MessageID);
if (!Ty.isParseError() && !isa<IdentTypeRepr>(Ty.get()) &&
!isa<ErrorTypeRepr>(Ty.get())) {
diagnose(Ty.get()->getStartLoc(), NonIdentifierTypeMessageID, Ty.get())
.highlight(Ty.get()->getSourceRange());
Ty.setIsParseError();
Ty = makeParserResult(
Ty, new (Context) ErrorTypeRepr(Ty.get()->getSourceRange()));
}
assert(Ty.isNull() ||
isa<IdentTypeRepr>(Ty.get()) ||
isa<ErrorTypeRepr>(Ty.get()));
return Ty;
}
示例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: make_pair
/// 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: parseGenericWhereClause
/// parseGenericWhereClause - Parse a 'where' clause, which places additional
/// constraints on generic parameters or types based on them.
///
/// where-clause:
/// 'where' requirement (',' requirement) *
///
/// requirement:
/// conformance-requirement
/// same-type-requirement
///
/// conformance-requirement:
/// type-identifier ':' type-identifier
/// type-identifier ':' type-composition
///
/// same-type-requirement:
/// type-identifier '==' type
ParserStatus Parser::parseGenericWhereClause(
SourceLoc &WhereLoc,
SmallVectorImpl<RequirementRepr> &Requirements,
bool &FirstTypeInComplete) {
ParserStatus Status;
// Parse the 'where'.
WhereLoc = consumeToken(tok::kw_where);
FirstTypeInComplete = false;
do {
// Parse the leading type-identifier.
ParserResult<TypeRepr> FirstType = parseTypeIdentifier();
if (FirstType.isNull()) {
Status.setIsParseError();
if (FirstType.hasCodeCompletion()) {
Status.setHasCodeCompletion();
FirstTypeInComplete = true;
}
break;
}
if (Tok.is(tok::colon)) {
// A conformance-requirement.
SourceLoc ColonLoc = consumeToken();
// Parse the protocol or composition.
ParserResult<TypeRepr> Protocol = parseTypeIdentifierOrTypeComposition();
if (Protocol.isNull()) {
Status.setIsParseError();
if (Protocol.hasCodeCompletion())
Status.setHasCodeCompletion();
break;
}
// Add the requirement.
Requirements.push_back(RequirementRepr::getTypeConstraint(FirstType.get(),
ColonLoc, Protocol.get()));
} else if ((Tok.isAnyOperator() && Tok.getText() == "==") ||
Tok.is(tok::equal)) {
// A same-type-requirement
if (Tok.is(tok::equal)) {
diagnose(Tok, diag::requires_single_equal)
.fixItReplace(SourceRange(Tok.getLoc()), "==");
}
SourceLoc EqualLoc = consumeToken();
// Parse the second type.
ParserResult<TypeRepr> SecondType = parseType();
if (SecondType.isNull()) {
Status.setIsParseError();
if (SecondType.hasCodeCompletion())
Status.setHasCodeCompletion();
break;
}
// Add the requirement
Requirements.push_back(RequirementRepr::getSameType(FirstType.get(),
EqualLoc,
SecondType.get()));
} else {
diagnose(Tok, diag::expected_requirement_delim);
Status.setIsParseError();
break;
}
// If there's a comma, keep parsing the list.
} while (consumeIf(tok::comma));
return Status;
}
示例10: 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());
//.........这里部分代码省略.........
示例11: makeParserResult
/// parseType
/// type:
/// attribute-list type-function
/// attribute-list type-array
///
/// type-function:
/// type-simple '->' type
///
ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
bool HandleCodeCompletion) {
// Parse attributes.
TypeAttributes attrs;
parseTypeAttributeList(attrs);
// Parse Generic Parameters. Generic Parameters are visible in the function
// body.
GenericParamList *generics = nullptr;
if (isInSILMode()) {
generics = maybeParseGenericParams().getPtrOrNull();
}
ParserResult<TypeRepr> ty = parseTypeSimple(MessageID, HandleCodeCompletion);
if (ty.hasCodeCompletion())
return makeParserCodeCompletionResult<TypeRepr>();
if (ty.isNull())
return nullptr;
// Parse a throws specifier. 'throw' is probably a typo for 'throws',
// but in local contexts we could just be at the end of a statement,
// so we need to check for the arrow.
ParserPosition beforeThrowsPos;
SourceLoc throwsLoc;
bool rethrows = false;
if (Tok.isAny(tok::kw_throws, tok::kw_rethrows) ||
(Tok.is(tok::kw_throw) && peekToken().is(tok::arrow))) {
if (Tok.is(tok::kw_throw)) {
diagnose(Tok.getLoc(), diag::throw_in_function_type)
.fixItReplace(Tok.getLoc(), "throws");
}
beforeThrowsPos = getParserPosition();
rethrows = Tok.is(tok::kw_rethrows);
throwsLoc = consumeToken();
}
// Handle type-function if we have an arrow.
SourceLoc arrowLoc;
if (consumeIf(tok::arrow, arrowLoc)) {
ParserResult<TypeRepr> SecondHalf =
parseType(diag::expected_type_function_result);
if (SecondHalf.hasCodeCompletion())
return makeParserCodeCompletionResult<TypeRepr>();
if (SecondHalf.isNull())
return nullptr;
if (rethrows) {
// 'rethrows' is only allowed on function declarations for now.
diagnose(throwsLoc, diag::rethrowing_function_type);
}
auto fnTy = new (Context) FunctionTypeRepr(generics, ty.get(),
throwsLoc,
arrowLoc,
SecondHalf.get());
return makeParserResult(applyAttributeToType(fnTy, attrs));
} else if (throwsLoc.isValid()) {
// Don't consume 'throws', so we can emit a more useful diagnostic when
// parsing a function decl.
restoreParserPosition(beforeThrowsPos);
return ty;
}
// Only function types may be generic.
if (generics) {
auto brackets = generics->getSourceRange();
diagnose(brackets.Start, diag::generic_non_function);
}
// Parse legacy array types for migration.
while (ty.isNonNull() && !Tok.isAtStartOfLine()) {
if (Tok.is(tok::l_square)) {
ty = parseTypeArray(ty.get());
} else {
break;
}
}
if (ty.isNonNull() && !ty.hasCodeCompletion()) {
ty = makeParserResult(applyAttributeToType(ty.get(), attrs));
}
return ty;
}
示例12: parsePatternTuple
/// Parse a pattern.
/// pattern ::= identifier
/// pattern ::= '_'
/// pattern ::= pattern-tuple
/// pattern ::= 'var' pattern
/// pattern ::= 'let' pattern
///
ParserResult<Pattern> Parser::parsePattern() {
switch (Tok.getKind()) {
case tok::l_paren:
return parsePatternTuple();
case tok::kw__:
return makeParserResult(new (Context) AnyPattern(consumeToken(tok::kw__)));
case tok::identifier: {
Identifier name;
SourceLoc loc = consumeIdentifier(&name);
bool isLet = InVarOrLetPattern != IVOLP_InVar;
return makeParserResult(createBindingFromPattern(loc, name, isLet));
}
case tok::code_complete:
if (!CurDeclContext->isNominalTypeOrNominalTypeExtensionContext()) {
// This cannot be an overridden property, so just eat the token. We cannot
// code complete anything here -- we expect an identifier.
consumeToken(tok::code_complete);
}
return nullptr;
case tok::kw_var:
case tok::kw_let: {
bool isLet = Tok.is(tok::kw_let);
SourceLoc varLoc = consumeToken();
// '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 = parsePattern();
if (subPattern.hasCodeCompletion())
return makeParserCodeCompletionResult<Pattern>();
if (subPattern.isNull())
return nullptr;
return makeParserResult(new (Context) VarPattern(varLoc, isLet,
subPattern.get()));
}
default:
if (Tok.isKeyword() &&
(peekToken().is(tok::colon) || peekToken().is(tok::equal))) {
diagnose(Tok, diag::expected_pattern_is_keyword, Tok.getText());
SourceLoc Loc = Tok.getLoc();
consumeToken();
return makeParserErrorResult(new (Context) AnyPattern(Loc));
}
diagnose(Tok, diag::expected_pattern);
return nullptr;
}
}
示例13: parseDefaultArgument
static ParserStatus parseDefaultArgument(Parser &P,
Parser::DefaultArgumentInfo *defaultArgs,
unsigned argIndex,
ExprHandle *&init,
Parser::ParameterContextKind paramContext) {
SourceLoc equalLoc = P.consumeToken(tok::equal);
// Enter a fresh default-argument context with a meaningless parent.
// We'll change the parent to the function later after we've created
// that declaration.
auto initDC =
P.Context.createDefaultArgumentContext(P.CurDeclContext, argIndex);
Parser::ParseFunctionBody initScope(P, initDC);
ParserResult<Expr> initR = P.parseExpr(diag::expected_init_value);
// Give back the default-argument context if we didn't need it.
if (!initScope.hasClosures()) {
P.Context.destroyDefaultArgumentContext(initDC);
// Otherwise, record it if we're supposed to accept default
// arguments here.
} else if (defaultArgs) {
defaultArgs->ParsedContexts.push_back(initDC);
}
Diag<> diagID = { DiagID() };
switch (paramContext) {
case Parser::ParameterContextKind::Function:
case Parser::ParameterContextKind::Operator:
case Parser::ParameterContextKind::Initializer:
break;
case Parser::ParameterContextKind::Closure:
diagID = diag::no_default_arg_closure;
break;
case Parser::ParameterContextKind::Subscript:
diagID = diag::no_default_arg_subscript;
break;
case Parser::ParameterContextKind::Curried:
diagID = diag::no_default_arg_curried;
break;
}
assert(((diagID.ID != DiagID()) == !defaultArgs ||
// Sometimes curried method parameter lists get default arg info.
// Remove this when they go away.
paramContext == Parser::ParameterContextKind::Curried) &&
"Default arguments specified for an unexpected parameter list kind");
if (diagID.ID != DiagID()) {
auto inFlight = P.diagnose(equalLoc, diagID);
if (initR.isNonNull())
inFlight.fixItRemove(SourceRange(equalLoc, initR.get()->getEndLoc()));
return ParserStatus();
}
defaultArgs->HasDefaultArgument = true;
if (initR.hasCodeCompletion())
return makeParserCodeCompletionStatus();
if (initR.isNull())
return makeParserError();
init = ExprHandle::get(P.Context, initR.get());
return ParserStatus();
}
示例14: 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;
ParserStatus Status = parseList(tok::r_paren, LPLoc, RPLoc,
tok::comma, /*OptionalSep=*/false,
/*AllowSepAfterLast=*/false,
diag::expected_rparen_tuple_type_list,
[&] () -> ParserStatus {
// If this is an inout marker in an argument list, consume the inout.
SourceLoc InOutLoc;
consumeIf(tok::kw_inout, InOutLoc);
// If the tuple element starts with "ident :", then
// the identifier is an element tag, and it is followed by a type
// annotation.
if (Tok.canBeArgumentLabel() && peekToken().is(tok::colon)) {
// Consume the name
Identifier name;
if (!Tok.is(tok::kw__))
name = Context.getIdentifier(Tok.getText());
SourceLoc nameLoc = consumeToken();
// Consume the ':'.
consumeToken(tok::colon);
// Parse the type annotation.
ParserResult<TypeRepr> type = parseType(diag::expected_type);
if (type.hasCodeCompletion())
return makeParserCodeCompletionStatus();
if (type.isNull())
return makeParserError();
// 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));
ElementsR.push_back(
new (Context) NamedTypeRepr(name, type.get(), nameLoc));
} else {
// Otherwise, this has to be a type.
ParserResult<TypeRepr> type = parseType();
if (type.hasCodeCompletion())
return makeParserCodeCompletionStatus();
if (type.isNull())
return makeParserError();
if (InOutLoc.isValid())
type = makeParserResult(new (Context) InOutTypeRepr(type.get(),
InOutLoc));
ElementsR.push_back(type.get());
}
// Parse '= expr' here so we can complain about it directly, rather
// than dying when we see it.
if (Tok.is(tok::equal)) {
SourceLoc equalLoc = consumeToken(tok::equal);
auto init = parseExpr(diag::expected_init_value);
auto inFlight = diagnose(equalLoc, diag::tuple_type_init);
if (init.isNonNull())
inFlight.fixItRemove(SourceRange(equalLoc, init.get()->getEndLoc()));
}
if (Tok.isEllipsis()) {
if (EllipsisLoc.isValid()) {
diagnose(Tok, diag::multiple_ellipsis_in_tuple)
.highlight(EllipsisLoc)
.fixItRemove(Tok.getLoc());
(void)consumeToken();
} else {
EllipsisLoc = consumeToken();
EllipsisIdx = ElementsR.size() - 1;
}
}
return makeParserSuccess();
});
if (EllipsisLoc.isValid() && ElementsR.empty()) {
EllipsisLoc = SourceLoc();
}
if (EllipsisLoc.isInvalid())
EllipsisIdx = ElementsR.size();
return makeParserResult(Status,
//.........这里部分代码省略.........
示例15: parseGenericWhereClause
/// parseGenericWhereClause - Parse a 'where' clause, which places additional
/// constraints on generic parameters or types based on them.
///
/// where-clause:
/// 'where' requirement (',' requirement) *
///
/// requirement:
/// conformance-requirement
/// same-type-requirement
///
/// conformance-requirement:
/// type-identifier ':' type-identifier
/// type-identifier ':' type-composition
///
/// same-type-requirement:
/// type-identifier '==' type
ParserStatus Parser::parseGenericWhereClause(
SourceLoc &WhereLoc,
SmallVectorImpl<RequirementRepr> &Requirements,
bool &FirstTypeInComplete,
bool AllowLayoutConstraints) {
SyntaxParsingContext ClauseContext(SyntaxContext,
SyntaxKind::GenericWhereClause);
ParserStatus Status;
// Parse the 'where'.
WhereLoc = consumeToken(tok::kw_where);
FirstTypeInComplete = false;
SyntaxParsingContext ReqListContext(SyntaxContext,
SyntaxKind::GenericRequirementList);
bool HasNextReq;
do {
SyntaxParsingContext ReqContext(SyntaxContext, SyntaxContextKind::Syntax);
// Parse the leading type. It doesn't necessarily have to be just a type
// identifier if we're dealing with a same-type constraint.
ParserResult<TypeRepr> FirstType = parseType();
if (FirstType.hasCodeCompletion()) {
Status.setHasCodeCompletion();
FirstTypeInComplete = true;
}
if (FirstType.isNull()) {
Status.setIsParseError();
break;
}
if (Tok.is(tok::colon)) {
// A conformance-requirement.
SourceLoc ColonLoc = consumeToken();
ReqContext.setCreateSyntax(SyntaxKind::ConformanceRequirement);
if (Tok.is(tok::identifier) &&
getLayoutConstraint(Context.getIdentifier(Tok.getText()), Context)
->isKnownLayout()) {
// Parse a layout constraint.
Identifier LayoutName;
auto LayoutLoc = consumeIdentifier(&LayoutName);
auto LayoutInfo = parseLayoutConstraint(LayoutName);
if (!LayoutInfo->isKnownLayout()) {
// There was a bug in the layout constraint.
Status.setIsParseError();
}
auto Layout = LayoutInfo;
// Types in SIL mode may contain layout constraints.
if (!AllowLayoutConstraints && !isInSILMode()) {
diagnose(LayoutLoc,
diag::layout_constraints_only_inside_specialize_attr);
} else {
// Add the layout requirement.
Requirements.push_back(RequirementRepr::getLayoutConstraint(
FirstType.get(), ColonLoc,
LayoutConstraintLoc(Layout, LayoutLoc)));
}
} else {
// Parse the protocol or composition.
ParserResult<TypeRepr> Protocol = parseType();
if (Protocol.isNull()) {
Status.setIsParseError();
if (Protocol.hasCodeCompletion())
Status.setHasCodeCompletion();
break;
}
// Add the requirement.
Requirements.push_back(RequirementRepr::getTypeConstraint(
FirstType.get(), ColonLoc, Protocol.get()));
}
} else if ((Tok.isAnyOperator() && Tok.getText() == "==") ||
Tok.is(tok::equal)) {
ReqContext.setCreateSyntax(SyntaxKind::SameTypeRequirement);
// A same-type-requirement
if (Tok.is(tok::equal)) {
diagnose(Tok, diag::requires_single_equal)
.fixItReplace(SourceRange(Tok.getLoc()), "==");
}
SourceLoc EqualLoc = consumeToken();
// Parse the second type.
ParserResult<TypeRepr> SecondType = parseType();
if (SecondType.isNull()) {
//.........这里部分代码省略.........