当前位置: 首页>>代码示例>>C++>>正文


C++ ParserResult::isNull方法代码示例

本文整理汇总了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));
}
开发者ID:nauzetvm,项目名称:Apple-Swift,代码行数:48,代码来源:ParseType.cpp

示例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));
}
开发者ID:ditedondaw,项目名称:swift,代码行数:33,代码来源:ParsePattern.cpp

示例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;
}
开发者ID:nauzetvm,项目名称:Apple-Swift,代码行数:33,代码来源:ParseType.cpp

示例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;
}
开发者ID:yasirmcs,项目名称:swift,代码行数:61,代码来源:ParsePattern.cpp

示例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()));
}
开发者ID:ditedondaw,项目名称:swift,代码行数:47,代码来源:ParsePattern.cpp

示例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;
}
开发者ID:nauzetvm,项目名称:Apple-Swift,代码行数:18,代码来源:ParseType.cpp

示例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;
}
开发者ID:ditedondaw,项目名称:swift,代码行数:24,代码来源:ParsePattern.cpp

示例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);
}
开发者ID:ditedondaw,项目名称:swift,代码行数:26,代码来源:ParsePattern.cpp

示例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;
}
开发者ID:464033679,项目名称:swift,代码行数:85,代码来源:ParseGeneric.cpp

示例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());
//.........这里部分代码省略.........
开发者ID:nauzetvm,项目名称:Apple-Swift,代码行数:101,代码来源:ParseType.cpp

示例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;
}
开发者ID:nauzetvm,项目名称:Apple-Swift,代码行数:91,代码来源:ParseType.cpp

示例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;
  }
}
开发者ID:ditedondaw,项目名称:swift,代码行数:69,代码来源:ParsePattern.cpp

示例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();
}
开发者ID:ditedondaw,项目名称:swift,代码行数:67,代码来源:ParsePattern.cpp

示例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,
//.........这里部分代码省略.........
开发者ID:A-Goretsky,项目名称:swift,代码行数:101,代码来源:ParseType.cpp

示例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()) {
//.........这里部分代码省略.........
开发者ID:JoniusLi,项目名称:swift-1,代码行数:101,代码来源:ParseGeneric.cpp


注:本文中的ParserResult::isNull方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。