示例#1
0
  // The extraRecoverySet is needed for the foo(bar<x, 1, y>(z)) case, to tell whether we should
  // stop
  // on expression-indicating symbols or not
  private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet) {
    // Disabling token merge is required for cases like
    //    Int?.(Foo) -> Bar
    // we don't support this case now
    //        myBuilder.disableJoiningComplexTokens();
    PsiBuilder.Marker typeRefMarker = mark();
    parseAnnotations(false);

    if (at(IDENTIFIER) || at(PACKAGE_KEYWORD)) {
      parseUserType();
    } else if (at(HASH)) {
      parseTupleType();
    } else if (at(LPAR)) {
      PsiBuilder.Marker functionOrParenthesizedType = mark();

      // This may be a function parameter list or just a prenthesized type
      advance(); // LPAR
      parseTypeRefContents(TokenSet.EMPTY)
          .drop(); // parenthesized types, no reference element around it is needed

      if (at(RPAR)) {
        advance(); // RPAR
        if (at(ARROW)) {
          // It's a function type with one parameter specified
          //    (A) -> B
          functionOrParenthesizedType.rollbackTo();
          parseFunctionType();
        } else {
          // It's a parenthesized type
          //    (A)
          functionOrParenthesizedType.drop();
        }
      } else {
        // This must be a function type
        //   (A, B) -> C
        // or
        //   (a : A) -> C
        functionOrParenthesizedType.rollbackTo();
        parseFunctionType();
      }

    } else if (at(CAPITALIZED_THIS_KEYWORD)) {
      parseSelfType();
    } else {
      errorWithRecovery(
          "Type expected",
          TokenSet.orSet(
              TOPLEVEL_OBJECT_FIRST,
              TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON),
              extraRecoverySet));
    }

    while (at(QUEST)) {
      PsiBuilder.Marker precede = typeRefMarker.precede();

      advance(); // QUEST
      typeRefMarker.done(NULLABLE_TYPE);

      typeRefMarker = precede;
    }

    if (at(DOT)) {
      // This is a receiver for a function type
      //  A.(B) -> C
      //   ^

      PsiBuilder.Marker functionType = typeRefMarker.precede();
      PsiBuilder.Marker receiverType = typeRefMarker.precede();
      typeRefMarker.done(TYPE_REFERENCE);
      receiverType.done(FUNCTION_TYPE_RECEIVER);

      advance(); // DOT

      if (at(LPAR)) {
        parseFunctionTypeContents().drop();
      } else {
        error("Expecting function type");
      }
      typeRefMarker = functionType.precede();

      functionType.done(FUNCTION_TYPE);
    }
    //        myBuilder.restoreJoiningComplexTokensState();
    return typeRefMarker;
  }