Пример #1
0
  /*
   * object
   *   : "object" SimpleName? ":" delegationSpecifier{","}? classBody?
   *   ;
   */
  void parseObject(boolean named, boolean optionalBody) {
    assert _at(OBJECT_KEYWORD);

    advance(); // OBJECT_KEYWORD

    if (named) {
      PsiBuilder.Marker propertyDeclaration = mark();
      if (!parseIdeTemplate()) {
        expect(IDENTIFIER, "Expecting object name", TokenSet.create(LBRACE));
      }
      propertyDeclaration.done(OBJECT_DECLARATION_NAME);
    } else {
      if (at(IDENTIFIER)) {
        error("An object expression cannot bind a name");
      }
    }

    if (optionalBody) {
      if (at(COLON)) {
        advance(); // COLON
        parseDelegationSpecifierList();
      }
      if (at(LBRACE)) {
        parseClassBody();
      }
    } else {
      if (at(LBRACE)) {
        parseClassBody();
      } else {
        expect(COLON, "Expecting ':'", TokenSet.create(IDENTIFIER, PACKAGE_KEYWORD));
        parseDelegationSpecifierList();
        parseClassBody();
      }
    }
  }
Пример #2
0
  /*
   * 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;
  }