コード例 #1
0
ファイル: JetParsing.java プロジェクト: univerio/kotlin
  /*
   *preamble
   *  : namespaceHeader? import*
   *  ;
   */
  private void parsePreamble(boolean imports) {
    /*
     * namespaceHeader
     *   : modifiers "namespace" SimpleName{"."} SEMI?
     *   ;
     */
    PsiBuilder.Marker namespaceHeader = mark();
    PsiBuilder.Marker firstEntry = mark();
    parseModifierList(MODIFIER_LIST, true);

    if (at(PACKAGE_KEYWORD)) {
      advance(); // PACKAGE_KEYWORD

      parseNamespaceName();

      if (at(LBRACE)) {
        // Because it's blocked namespace and it will be parsed as one of top level objects
        firstEntry.rollbackTo();
        namespaceHeader.done(NAMESPACE_HEADER);
        return;
      }

      firstEntry.drop();

      consumeIf(SEMICOLON);
    } else {
      firstEntry.rollbackTo();
    }
    namespaceHeader.done(NAMESPACE_HEADER);

    if (imports) parseImportDirectives();
  }
コード例 #2
0
  @Nullable
  private PsiBuilder.Marker parseUnary(final PsiBuilder builder) {
    final IElementType tokenType = builder.getTokenType();

    if (PREFIX_OPS.contains(tokenType)) {
      final PsiBuilder.Marker unary = builder.mark();
      builder.advanceLexer();

      final PsiBuilder.Marker operand = parseUnary(builder);
      if (operand == null) {
        error(builder, JavaErrorMessages.message("expected.expression"));
      }

      unary.done(JavaElementType.PREFIX_EXPRESSION);
      return unary;
    } else if (tokenType == JavaTokenType.LPARENTH) {
      final PsiBuilder.Marker typeCast = builder.mark();
      builder.advanceLexer();

      ReferenceParser.TypeInfo typeInfo =
          myParser
              .getReferenceParser()
              .parseTypeInfo(
                  builder,
                  ReferenceParser.EAT_LAST_DOT
                      | ReferenceParser.WILDCARD
                      | ReferenceParser.CONJUNCTIONS
                      | ReferenceParser.INCOMPLETE_ANNO);
      if (typeInfo == null || !expect(builder, JavaTokenType.RPARENTH)) {
        typeCast.rollbackTo();
        return parsePostfix(builder);
      }

      if (PREF_ARITHMETIC_OPS.contains(builder.getTokenType()) && !typeInfo.isPrimitive) {
        typeCast.rollbackTo();
        return parsePostfix(builder);
      }

      final PsiBuilder.Marker expr = parseUnary(builder);
      if (expr == null) {
        if (!typeInfo
            .isParameterized) { // cannot parse correct parenthesized expression after correct
                                // parameterized type
          typeCast.rollbackTo();
          return parsePostfix(builder);
        } else {
          error(builder, JavaErrorMessages.message("expected.expression"));
        }
      }

      typeCast.done(JavaElementType.TYPE_CAST_EXPRESSION);
      return typeCast;
    } else {
      return parsePostfix(builder);
    }
  }
コード例 #3
0
  /*
   * "this" ("<" type ">")? label?
   */
  private void parseSuperExpression() {
    assert _at(SUPER_KEYWORD);
    PsiBuilder.Marker mark = mark();

    PsiBuilder.Marker superReference = mark();
    advance(); // SUPER_KEYWORD
    superReference.done(REFERENCE_EXPRESSION);

    if (at(LT)) {
      // This may be "super < foo" or "super<foo>", thus the backtracking
      PsiBuilder.Marker supertype = mark();

      myBuilder.disableNewlines();
      advance(); // LT

      myJetParsing.parseTypeRef();

      if (at(GT)) {
        advance(); // GT
        supertype.drop();
      } else {
        supertype.rollbackTo();
      }
      myBuilder.restoreNewlinesState();
    }
    parseLabelOnTheSameLine();

    mark.done(SUPER_EXPRESSION);
  }
コード例 #4
0
  /*
   * callableReference
   *   : (userType "?"*)? "::" SimpleName
   *   ;
   */
  private boolean parseDoubleColonExpression() {
    PsiBuilder.Marker expression = mark();

    if (!at(COLONCOLON)) {
      PsiBuilder.Marker typeReference = mark();
      myJetParsing.parseUserType();
      typeReference = myJetParsing.parseNullableTypeSuffix(typeReference);
      typeReference.done(TYPE_REFERENCE);

      if (!at(COLONCOLON)) {
        expression.rollbackTo();
        return false;
      }
    }

    advance(); // COLONCOLON

    if (at(CLASS_KEYWORD)) {
      advance(); // CLASS_KEYWORD
      expression.done(CLASS_LITERAL_EXPRESSION);
    } else {
      parseSimpleNameExpression();
      expression.done(CALLABLE_REFERENCE_EXPRESSION);
    }

    return true;
  }
コード例 #5
0
 protected boolean parseTupleExpression(
     boolean stopOnIn, boolean isTargetExpression, final boolean oldTest) {
   PsiBuilder.Marker expr = myBuilder.mark();
   boolean exprParseResult =
       oldTest ? parseOldTestExpression() : parseTestExpression(stopOnIn, isTargetExpression);
   if (!exprParseResult) {
     expr.drop();
     return false;
   }
   if (myBuilder.getTokenType() == PyTokenTypes.COMMA) {
     while (myBuilder.getTokenType() == PyTokenTypes.COMMA) {
       myBuilder.advanceLexer();
       PsiBuilder.Marker expr2 = myBuilder.mark();
       exprParseResult =
           oldTest ? parseOldTestExpression() : parseTestExpression(stopOnIn, isTargetExpression);
       if (!exprParseResult) {
         expr2.rollbackTo();
         break;
       }
       expr2.drop();
     }
     expr.done(PyElementTypes.TUPLE_EXPRESSION);
   } else {
     expr.drop();
   }
   return true;
 }
コード例 #6
0
  public static void parse(PsiBuilder builder, GroovyParser parser) {

    PsiBuilder.Marker annArgs = builder.mark();
    if (!ParserUtils.getToken(builder, mLPAREN)) {
      annArgs.done(ANNOTATION_ARGUMENTS);
      return;
    }

    if (ParserUtils.lookAhead(builder, mIDENT, mASSIGN)) {
      if (!parseAnnotationMemberValuePairs(builder, parser)) {
        annArgs.rollbackTo();
        return;
      }
    } else {
      PsiBuilder.Marker pairMarker = builder.mark();
      if (!parseAnnotationMemberValueInitializer(builder, parser)) {
        pairMarker.drop();
      } else {
        pairMarker.done(ANNOTATION_MEMBER_VALUE_PAIR);
      }
    }

    ParserUtils.getToken(builder, mNLS);

    if (!ParserUtils.getToken(builder, mRPAREN)) {
      builder.error(GroovyBundle.message("rparen.expected"));
    }
    annArgs.done(ANNOTATION_ARGUMENTS);
  }
コード例 #7
0
  public static boolean parse(
      PsiBuilder builder, boolean isInClass, boolean isInAnnotation, GroovyParser parser) {
    PsiBuilder.Marker declMarker = builder.mark();
    // allows error messages
    boolean modifiersParsed = Modifiers.parse(builder, parser);

    final boolean methodStart = mLT == builder.getTokenType();
    final IElementType type =
        parseAfterModifiers(
            builder, isInClass, isInAnnotation, parser, declMarker, modifiersParsed);
    if (type == WRONGWAY) {
      if (modifiersParsed && methodStart) {
        declMarker.error(GroovyBundle.message("method.definitions.expected"));
        return false;
      }

      declMarker.rollbackTo();
      if (modifiersParsed) {
        builder.error(GroovyBundle.message("variable.definitions.expected"));
      }

      return false;
    }

    if (type != null) {
      declMarker.done(type);
    } else {
      declMarker.drop();
    }
    return true;
  }
コード例 #8
0
 private void getNextTokenValue(PsiBuilder builder) {
   PsiBuilder.Marker rb = builder.mark();
   builder.advanceLexer();
   nextToken = builder.getTokenType();
   nextTokenText = builder.getTokenText();
   rb.rollbackTo();
 }
コード例 #9
0
  @Nullable
  private static IElementType getGtTokenType(final PsiBuilder builder) {
    final PsiBuilder.Marker sp = builder.mark();

    IElementType tokenType = builder.getTokenType();
    if (tokenType == JavaTokenType.GT) {
      builder.advanceLexer();
      if (builder.getTokenType() == JavaTokenType.GT) {
        builder.advanceLexer();
        if (builder.getTokenType() == JavaTokenType.GT) {
          builder.advanceLexer();
          if (builder.getTokenType() == JavaTokenType.EQ) {
            tokenType = JavaTokenType.GTGTGTEQ;
          } else {
            tokenType = JavaTokenType.GTGTGT;
          }
        } else if (builder.getTokenType() == JavaTokenType.EQ) {
          tokenType = JavaTokenType.GTGTEQ;
        } else {
          tokenType = JavaTokenType.GTGT;
        }
      } else if (builder.getTokenType() == JavaTokenType.EQ) {
        tokenType = JavaTokenType.GE;
      }
    }

    sp.rollbackTo();
    return tokenType;
  }
コード例 #10
0
  @Nullable
  private PsiBuilder.Marker parseLambdaExpression(
      final PsiBuilder builder, final boolean typed, @Nullable final PsiBuilder.Marker typeList) {
    final PsiBuilder.Marker start = typeList != null ? typeList.precede() : builder.mark();

    myParser.getDeclarationParser().parseLambdaParameterList(builder, typed);

    if (!expect(builder, JavaTokenType.ARROW)) {
      start.rollbackTo();
      return null;
    }

    final PsiBuilder.Marker body;
    if (builder.getTokenType() == JavaTokenType.LBRACE) {
      body = myParser.getStatementParser().parseCodeBlock(builder);
    } else {
      body = parse(builder);
    }

    if (body == null) {
      builder.error(JavaErrorMessages.message("expected.lbrace"));
    }

    start.done(JavaElementType.LAMBDA_EXPRESSION);
    return start;
  }
コード例 #11
0
  public static boolean parseMasonMethod(
      PsiBuilder b, int l, IElementType closeToken, IElementType statementTokenType) {
    boolean r = false;

    PsiBuilder.Marker methodMarker = b.mark();
    b.advanceLexer();
    PsiBuilder.Marker subMarker = b.mark();
    if (PerlParserUtil.consumeToken(b, IDENTIFIER)) {
      subMarker.collapse(SUB);
      PerlParserImpl.method_signature(b, l);
      if (PerlParserUtil.consumeToken(b, MASON_TAG_CLOSER)) {
        PsiBuilder.Marker blockMarker = b.mark();
        PerlParserImpl.block_content(b, l);

        if (b.getTokenType() == closeToken) {
          blockMarker.done(BLOCK);
          blockMarker.setCustomEdgeTokenBinders(
              WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER);
          b.advanceLexer();
          methodMarker.done(statementTokenType);
          r = true;
        }
      }
    }

    if (!r) {
      methodMarker.rollbackTo();
    }

    return r || recoverToGreedy(b, closeToken, "Error");
  }
コード例 #12
0
ファイル: ForStatement.java プロジェクト: jexp/idea2
  private static boolean tradForClauseParse(PsiBuilder builder, GroovyParser parser) {

    PsiBuilder.Marker marker = builder.mark();

    if (ParserUtils.getToken(builder, mSEMI)
        || (Declaration.parse(builder, false, parser) && ParserUtils.getToken(builder, mSEMI))) {
      StrictContextExpression.parse(builder, parser);
      ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected"));
      ParserUtils.getToken(builder, mNLS);
      if (!mRPAREN.equals(builder.getTokenType())) {
        controlExpressionListParse(builder, parser);
      }
    } else {
      marker.rollbackTo();
      marker = builder.mark();
      controlExpressionListParse(builder, parser);
      ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected"));
      StrictContextExpression.parse(builder, parser);
      ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected"));
      ParserUtils.getToken(builder, mNLS);
      if (!mRPAREN.equals(builder.getTokenType())) {
        controlExpressionListParse(builder, parser);
      }
    }

    marker.done(FOR_TRADITIONAL_CLAUSE);
    return true;
  }
コード例 #13
0
  public void parseArgumentList() {
    LOG.assertTrue(myBuilder.getTokenType() == PyTokenTypes.LPAR);
    final PsiBuilder.Marker arglist = myBuilder.mark();
    myBuilder.advanceLexer();
    PsiBuilder.Marker genexpr = myBuilder.mark();
    int argNumber = 0;
    while (myBuilder.getTokenType() != PyTokenTypes.RPAR) {
      argNumber++;
      if (argNumber > 1) {
        if (argNumber == 2 && atToken(PyTokenTypes.FOR_KEYWORD) && genexpr != null) {
          parseComprehension(genexpr, null, PyElementTypes.GENERATOR_EXPRESSION);
          genexpr = null;
          continue;
        } else if (matchToken(PyTokenTypes.COMMA)) {
          if (atToken(PyTokenTypes.RPAR)) {
            break;
          }
        } else {
          myBuilder.error(message("PARSE.expected.comma.or.rpar"));
          break;
        }
      }
      if (myBuilder.getTokenType() == PyTokenTypes.MULT
          || myBuilder.getTokenType() == PyTokenTypes.EXP) {
        final PsiBuilder.Marker starArgMarker = myBuilder.mark();
        myBuilder.advanceLexer();
        if (!parseSingleExpression(false)) {
          myBuilder.error(message("PARSE.expected.expression"));
        }
        starArgMarker.done(PyElementTypes.STAR_ARGUMENT_EXPRESSION);
      } else {
        if (myBuilder.getTokenType() == PyTokenTypes.IDENTIFIER) {
          final PsiBuilder.Marker keywordArgMarker = myBuilder.mark();
          myBuilder.advanceLexer();
          if (myBuilder.getTokenType() == PyTokenTypes.EQ) {
            myBuilder.advanceLexer();
            if (!parseSingleExpression(false)) {
              myBuilder.error(message("PARSE.expected.expression"));
            }
            keywordArgMarker.done(PyElementTypes.KEYWORD_ARGUMENT_EXPRESSION);
            continue;
          }
          keywordArgMarker.rollbackTo();
        }
        if (!parseSingleExpression(false)) {
          myBuilder.error(message("PARSE.expected.expression"));
          break;
        }
      }
    }

    if (genexpr != null) {
      genexpr.drop();
    }
    checkMatches(PyTokenTypes.RPAR, message("PARSE.expected.rpar"));
    arglist.done(PyElementTypes.ARGUMENT_LIST);
  }
コード例 #14
0
  @Nullable
  private PsiBuilder.Marker parseLambdaAfterParenth(
      final PsiBuilder builder, @Nullable final PsiBuilder.Marker typeList) {
    final boolean isLambda;
    final boolean isTyped;

    final IElementType nextToken1 = builder.lookAhead(1);
    final IElementType nextToken2 = builder.lookAhead(2);
    if (nextToken1 == JavaTokenType.RPARENTH && nextToken2 == JavaTokenType.ARROW) {
      isLambda = true;
      isTyped = false;
    } else if (nextToken1 == JavaTokenType.AT
        || ElementType.MODIFIER_BIT_SET.contains(nextToken1)
        || ElementType.PRIMITIVE_TYPE_BIT_SET.contains(nextToken1)) {
      isLambda = true;
      isTyped = true;
    } else if (nextToken1 == JavaTokenType.IDENTIFIER) {
      if (nextToken2 == JavaTokenType.COMMA
          || nextToken2 == JavaTokenType.RPARENTH && builder.lookAhead(3) == JavaTokenType.ARROW) {
        isLambda = true;
        isTyped = false;
      } else if (nextToken2 == JavaTokenType.ARROW) {
        isLambda = false;
        isTyped = false;
      } else {
        boolean arrow = false;

        final PsiBuilder.Marker marker = builder.mark();
        while (!builder.eof()) {
          builder.advanceLexer();
          final IElementType tokenType = builder.getTokenType();
          if (tokenType == JavaTokenType.ARROW) {
            arrow = true;
            break;
          }
          if (tokenType == JavaTokenType.RPARENTH) {
            arrow = builder.lookAhead(1) == JavaTokenType.ARROW;
            break;
          } else if (tokenType == JavaTokenType.LPARENTH
              || tokenType == JavaTokenType.SEMICOLON
              || tokenType == JavaTokenType.LBRACE
              || tokenType == JavaTokenType.RBRACE) {
            break;
          }
        }
        marker.rollbackTo();

        isLambda = arrow;
        isTyped = true;
      }
    } else {
      isLambda = false;
      isTyped = false;
    }

    return isLambda ? parseLambdaExpression(builder, isTyped, typeList) : null;
  }
コード例 #15
0
 private static boolean parseHasArgumentsBare(PerlBuilder b, int l) {
   PsiBuilder.Marker m = b.mark();
   if (parseHasArgumentsSequenceContent(b, l)) {
     m.done(COMMA_SEQUENCE_EXPR);
     return true;
   }
   m.rollbackTo();
   return false;
 }
コード例 #16
0
 private boolean rollbackOrDropAt(PsiBuilder.Marker rollbackMarker, IElementType dropAt) {
   if (at(dropAt)) {
     advance(); // dropAt
     rollbackMarker.drop();
     return true;
   }
   rollbackMarker.rollbackTo();
   return false;
 }
コード例 #17
0
 public static boolean parseTokens(
     PsiBuilder builder, boolean smart, int pin, IElementType... tokens) {
   PsiBuilder.Marker marker = builder.mark();
   boolean result = consumeTokens(builder, smart, pin, tokens);
   if (!result) {
     marker.rollbackTo();
   } else {
     marker.drop();
   }
   return result;
 }
コード例 #18
0
  private static boolean parseAnnotationMemberValuePairs(PsiBuilder builder, GroovyParser parser) {
    PsiBuilder.Marker annmvps = builder.mark();

    if (!parseAnnotationMemberValueSinglePair(builder, parser)) {
      annmvps.rollbackTo();
      return false;
    }

    while (ParserUtils.getToken(builder, mCOMMA)) {
      ParserUtils.getToken(builder, mNLS);

      if (!parseAnnotationMemberValueSinglePair(builder, parser)) {
        annmvps.rollbackTo();
        return false;
      }
    }

    annmvps.done(ANNOTATION_MEMBER_VALUE_PAIRS);
    return true;
  }
コード例 #19
0
  protected void rollbackTo(@NotNull final PsiBuilder.Marker marker) {
    if (myIndents.get(marker) == null) {
      throw new RuntimeException(
          "Parser can't rollback marker that was created by mark() method, use mark(true) instead");
    }
    myCurrentIndent = myIndents.get(marker);
    myNewLine = myNewLines.get(marker);

    myIndents.remove(marker);
    myNewLines.remove(marker);
    marker.rollbackTo();
  }
コード例 #20
0
 private static boolean parseHasArgumentsSequenceContent(PerlBuilder b, int l) {
   PsiBuilder.Marker m = b.mark();
   if (parseHasAttributeDefinitions(b, l)
       && (PerlParserUtil.consumeToken(b, OPERATOR_COMMA)
           || PerlParserUtil.consumeToken(b, OPERATOR_COMMA_ARROW))
       && PerlParserImpl.expr(b, l, -1)) {
     m.drop();
     return true;
   }
   m.rollbackTo();
   return false;
 }
コード例 #21
0
 private boolean parseEllipsis() {
   if (atToken(PyTokenTypes.DOT)) {
     final PsiBuilder.Marker maybeEllipsis = myBuilder.mark();
     myBuilder.advanceLexer();
     if (matchToken(PyTokenTypes.DOT) && matchToken(PyTokenTypes.DOT)) {
       maybeEllipsis.done(PyElementTypes.NONE_LITERAL_EXPRESSION);
       return true;
     }
     maybeEllipsis.rollbackTo();
   }
   return false;
 }
コード例 #22
0
  @Nullable
  private PsiBuilder.Marker parseClassAccessOrMethodReference(final PsiBuilder builder) {
    final PsiBuilder.Marker expr = builder.mark();

    final boolean primitive = ElementType.PRIMITIVE_TYPE_BIT_SET.contains(builder.getTokenType());
    if (myParser.getReferenceParser().parseType(builder, 0) == null) {
      expr.drop();
      return null;
    }

    final PsiBuilder.Marker result = continueClassAccessOrMethodReference(builder, expr, primitive);
    if (result == null) expr.rollbackTo();
    return result;
  }
コード例 #23
0
  private static boolean parseAnnotationMemberValueSinglePair(
      PsiBuilder builder, GroovyParser parser) {
    PsiBuilder.Marker annmvp = builder.mark();

    if (!ParserUtils.getToken(builder, mIDENT)) {
      annmvp.rollbackTo();
      return false;
    }

    if (!ParserUtils.getToken(builder, mASSIGN)) {
      annmvp.rollbackTo();
      return false;
    }

    ParserUtils.getToken(builder, mNLS);

    if (!parseAnnotationMemberValueInitializer(builder, parser)) {
      builder.error(GroovyBundle.message("annotation.member.value.initializer.expected"));
    }

    annmvp.done(ANNOTATION_MEMBER_VALUE_PAIR);
    return true;
  }
コード例 #24
0
  /*
   * callableReference
   *   : (userType "?"*)? "::" SimpleName typeArguments?
   *   ;
   */
  private boolean parseDoubleColonExpression() {
    PsiBuilder.Marker expression = mark();

    if (!at(COLONCOLON)) {
      PsiBuilder.Marker typeReference = mark();
      myJetParsing.parseUserType();
      typeReference = myJetParsing.parseNullableTypeSuffix(typeReference);
      typeReference.done(TYPE_REFERENCE);

      if (!at(COLONCOLON)) {
        expression.rollbackTo();
        return false;
      }
    }

    advance(); // COLONCOLON

    if (at(CLASS_KEYWORD)) {
      advance(); // CLASS_KEYWORD
      expression.done(CLASS_LITERAL_EXPRESSION);
    } else {
      parseSimpleNameExpression();

      if (at(LT)) {
        PsiBuilder.Marker typeArgumentList = mark();
        if (myJetParsing.tryParseTypeArgumentList(TYPE_ARGUMENT_LIST_STOPPERS)) {
          typeArgumentList.error("Type arguments are not allowed");
        } else {
          typeArgumentList.rollbackTo();
        }
      }

      expression.done(CALLABLE_REFERENCE_EXPRESSION);
    }

    return true;
  }
コード例 #25
0
  public static IElementType parseDefinitions(
      @NotNull PsiBuilder builder,
      boolean isInClass,
      boolean isInAnnotation,
      @Nullable String typeDefinitionName,
      boolean hasModifiers,
      boolean canBeTuple,
      @NotNull GroovyParser parser) {
    boolean isLParenth = builder.getTokenType() == GroovyTokenTypes.mLPAREN;

    boolean isStringName =
        builder.getTokenType() == GroovyTokenTypes.mSTRING_LITERAL
            || builder.getTokenType() == GroovyTokenTypes.mGSTRING_LITERAL;

    if (builder.getTokenType() != GroovyTokenTypes.mIDENT && !isStringName && !isLParenth) {
      builder.error(GroovyBundle.message("indentifier.or.string.or.left.parenth.literal.expected"));
      return GroovyElementTypes.WRONGWAY;
    }

    if (isLParenth && !canBeTuple) {
      builder.error(GroovyBundle.message("indentifier.or.string.or.left.parenth.literal.expected"));
      return GroovyElementTypes.WRONGWAY;
    }

    if (isInAnnotation && isStringName) {
      builder.error(GroovyBundle.message("string.name.unexpected"));
    }

    if (!isLParenth) { // id or string => method name
      PsiBuilder.Marker varMarker = builder.mark();

      final boolean isConstructor =
          isInClass
              && !isInAnnotation
              && typeDefinitionName != null
              && builder.getTokenType() == GroovyTokenTypes.mIDENT
              && typeDefinitionName.equals(builder.getTokenText());
      builder.advanceLexer();

      if (GroovyTokenTypes.mLPAREN != builder.getTokenType()) {
        varMarker.rollbackTo();
      } else {
        varMarker.drop();
        return parseMethod(builder, isInAnnotation, hasModifiers, parser, isConstructor);
      }
    }

    return parseVar(builder, isInClass, hasModifiers, parser, isLParenth);
  }
コード例 #26
0
ファイル: JetParsing.java プロジェクト: univerio/kotlin
  /*
   * class
   *   : modifiers ("class" | "trait") SimpleName
   *       typeParameters?
   *         modifiers ("(" primaryConstructorParameter{","} ")")?
   *       (":" attributes delegationSpecifier{","})?
   *       typeConstraints
   *       (classBody? | enumClassBody)
   *   ;
   */
  IElementType parseClass(boolean enumClass) {
    assert _atSet(CLASS_KEYWORD, TRAIT_KEYWORD);
    advance(); // CLASS_KEYWORD or TRAIT_KEYWORD

    if (!parseIdeTemplate()) {
      expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET);
    }
    boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);

    PsiBuilder.Marker beforeConstructorModifiers = mark();
    boolean hasConstructorModifiers = parseModifierList(PRIMARY_CONSTRUCTOR_MODIFIER_LIST, false);

    // Some modifiers found, but no parentheses following: class has already ended, and we are
    // looking at something else
    if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON)) {
      beforeConstructorModifiers.rollbackTo();
      return CLASS;
    }

    // We are still inside a class declaration
    beforeConstructorModifiers.drop();

    if (at(LPAR)) {
      parseValueParameterList(false, TokenSet.create(COLON, LBRACE));
    } else if (hasConstructorModifiers) {
      // A comprehensive error message for cases like:
      //    class A private : Foo
      // or
      //    class A private {
      error("Expecting primary constructor parameter list");
    }

    if (at(COLON)) {
      advance(); // COLON
      parseDelegationSpecifierList();
    }

    parseTypeConstraintsGuarded(typeParametersDeclared);

    if (at(LBRACE)) {
      if (enumClass) {
        parseEnumClassBody();
      } else {
        parseClassBody();
      }
    }

    return CLASS;
  }
コード例 #27
0
  @Nullable
  private static PsiBuilder.Marker parseClassObjectAccess(final PsiBuilder builder) {
    final PsiBuilder.Marker expr = builder.mark();

    if (ReferenceParser.parseType(builder, 0) == null) {
      expr.drop();
      return null;
    }

    if (builder.getTokenType() != JavaTokenType.DOT) {
      expr.rollbackTo();
      return null;
    }
    builder.advanceLexer();

    if (builder.getTokenType() != JavaTokenType.CLASS_KEYWORD) {
      expr.rollbackTo();
      return null;
    }
    builder.advanceLexer();

    expr.done(JavaElementType.CLASS_OBJECT_ACCESS_EXPRESSION);
    return expr;
  }
コード例 #28
0
ファイル: ForStatement.java プロジェクト: jexp/idea2
 private static boolean singleDeclNoInitParse(
     PsiBuilder builder,
     PsiBuilder.Marker marker,
     PsiBuilder.Marker declMarker,
     GroovyParser parser) {
   if (ParserUtils.getToken(builder, mIDENT)) {
     if (kIN.equals(builder.getTokenType()) || mCOLON.equals(builder.getTokenType())) {
       declMarker.done(PARAMETER);
       builder.advanceLexer();
       if (!ShiftExpression.parse(builder, parser)) {
         builder.error(GroovyBundle.message("expression.expected"));
       }
       marker.done(FOR_IN_CLAUSE);
       return true;
     } else {
       marker.rollbackTo();
       return false;
     }
   } else {
     declMarker.drop();
     marker.rollbackTo();
     return false;
   }
 }
コード例 #29
0
  private static boolean parseAssignment(PsiBuilder builder, GroovyParser parser) {
    if (ParserUtils.getToken(builder, GroovyTokenTypes.mASSIGN)) {
      PsiBuilder.Marker marker = builder.mark();
      ParserUtils.getToken(builder, GroovyTokenTypes.mNLS);

      if (!AssignmentExpression.parse(builder, parser, true)) {
        marker.rollbackTo();
        builder.error(GroovyBundle.message("expression.expected"));
        return false;
      } else {
        marker.drop();
        return true;
      }
    }
    return false;
  }
コード例 #30
0
  @Nullable
  private static PsiBuilder.Marker parseClassObjectAccess(
      PsiBuilder builder, PsiBuilder.Marker expr, boolean optionalClassKeyword) {
    final PsiBuilder.Marker mark = builder.mark();
    builder.advanceLexer();

    if (builder.getTokenType() == JavaTokenType.CLASS_KEYWORD) {
      mark.drop();
      builder.advanceLexer();
    } else {
      if (!optionalClassKeyword) return null;
      mark.rollbackTo();
      builder.error(".class expected");
    }

    expr.done(JavaElementType.CLASS_OBJECT_ACCESS_EXPRESSION);
    return expr;
  }