Пример #1
0
  /*
   * SimpleName{,}
   */
  private void parseFunctionLiteralShorthandParameterList() {
    PsiBuilder.Marker parameterList = mark();

    while (!eof()) {
      PsiBuilder.Marker parameter = mark();

      //            int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new
      // At(IDENTIFIER), new AtOffset(doubleArrowPos)));
      //            createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST,
      // false);

      expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW));

      parameter.done(VALUE_PARAMETER);

      if (at(COLON)) {
        PsiBuilder.Marker errorMarker = mark();
        advance(); // COLON
        myJetParsing.parseTypeRef();
        errorMarker.error(
            "To specify a type of a parameter or a return type, use the full notation: {(parameter : Type) : ReturnType -> ...}");
      } else if (at(ARROW)) {
        break;
      } else if (at(COMMA)) {
        advance(); // COMMA
      } else {
        error("Expecting '->' or ','");
        break;
      }
    }

    parameterList.done(VALUE_PARAMETER_LIST);
  }
Пример #2
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;
  }
Пример #3
0
 private void handleUselessRename() {
   if (at(AS_KEYWORD)) {
     PsiBuilder.Marker as = mark();
     advance(); // AS_KEYWORD
     consumeIf(IDENTIFIER);
     as.error("Cannot rename a all imported items to one identifier");
   }
 }
 protected static boolean recoverTo(PsiBuilder b, IElementType toElement, String errorMessage) {
   // recover bad code
   PsiBuilder.Marker errorMarker = b.mark();
   while (!b.eof() && b.getTokenType() != toElement) {
     b.advanceLexer();
     ;
   }
   errorMarker.error(errorMessage);
   return b.eof();
 }
 private void eofCleanup() {
   if (markingBlock) {
     blockMarker.error(message("ss.parsing.unclosed.statement", blockTokenText));
     markingBlock = false;
   }
   if (markingComment) {
     commentMarker.drop();
   }
   while (!statementsStack.isEmpty()) {
     statementsStack.pop().drop();
   }
 }
 @Override
 public boolean parseTerm(PsiBuilder b, int l) {
   if (b.getTokenType() == MASON_SELF_POINTER) {
     PsiBuilder.Marker m = b.mark();
     b.advanceLexer();
     if (nested_call(b, l)) {
       m.done(MASON_SIMPLE_DEREF_EXPR);
     } else {
       m.error("Error parsing filter expression");
     }
     return true;
   }
   return super.parseTerm(b, l);
 }
 private static boolean reportError(
     PsiBuilder builder,
     ErrorState state,
     Frame frame,
     IElementType elementType,
     boolean force,
     boolean advance) {
   String expectedText = state.getExpectedText(builder);
   boolean notEmpty = StringUtil.isNotEmpty(expectedText);
   if (force || notEmpty || advance) {
     String gotText =
         builder.eof()
             ? "unexpected end of file"
             : notEmpty
                 ? "got '" + builder.getTokenText() + "'"
                 : "'" + builder.getTokenText() + "' unexpected";
     String message = expectedText + gotText;
     if (advance) {
       PsiBuilder.Marker mark = builder.mark();
       builder.advanceLexer();
       mark.error(message);
     } else if (!force) {
       PsiBuilder.Marker extensionMarker = null;
       IElementType extensionTokenType = null;
       PsiBuilderImpl.ProductionMarker latestDoneMarker =
           elementType == null
               ? null
               : (PsiBuilderImpl.ProductionMarker) builder.getLatestDoneMarker();
       if (latestDoneMarker != null
           && frame.position >= latestDoneMarker.getStartIndex()
           && frame.position <= latestDoneMarker.getEndIndex()) {
         extensionMarker = ((PsiBuilder.Marker) latestDoneMarker).precede();
         extensionTokenType = latestDoneMarker.getTokenType();
         ((PsiBuilder.Marker) latestDoneMarker).drop();
       }
       builder.error(message);
       if (extensionMarker != null) extensionMarker.done(extensionTokenType);
     } else {
       builder.error(message);
     }
     builder.eof(); // skip whitespaces
     frame.errorReportedAt = builder.rawTokenIndex();
     return true;
   }
   return false;
 }
  private boolean parseAwaitExpression(boolean isTargetExpression) {
    if (atToken(PyTokenTypes.AWAIT_KEYWORD)) {
      final PsiBuilder.Marker expr = myBuilder.mark();
      myBuilder.advanceLexer();

      if (!parseMemberExpression(isTargetExpression)) {
        myBuilder.error(message("PARSE.expected.expression"));
        expr.done(PyElementTypes.PREFIX_EXPRESSION);
      } else {
        if (isTargetExpression) {
          expr.error("can't assign to await expression");
        } else {
          expr.done(PyElementTypes.PREFIX_EXPRESSION);
        }
      }

      return true;
    } else {
      return parseMemberExpression(isTargetExpression);
    }
  }
Пример #9
0
  /*
   * tupleType
   *   : "#" "(" type{","}? ")"
   *   : "#" "(" parameter{","} ")" // tuple with named entries, the names do not affect assignment compatibility
   *   ;
   */
  @Deprecated // Tuples are dropped, but parsing is left to minimize surprising. This code should be
  // removed some time (in Kotlin 1.0?)
  private void parseTupleType() {
    assert _at(HASH);

    PsiBuilder.Marker tuple = mark();

    myBuilder.disableNewlines();
    advance(); // HASH
    consumeIf(LPAR);

    if (!at(RPAR)) {
      while (true) {
        if (at(COLON)) {
          errorAndAdvance("Expecting a name for tuple entry");
        }

        if (at(IDENTIFIER) && lookahead(1) == COLON) {
          advance(); // IDENTIFIER
          advance(); // COLON
          parseTypeRef();
        } else if (TYPE_REF_FIRST.contains(tt())) {
          parseTypeRef();
        } else {
          error("Type expected");
          break;
        }
        if (!at(COMMA)) break;
        advance(); // COMMA
      }
    }

    consumeIf(RPAR);
    myBuilder.restoreNewlinesState();

    tuple.error("Tuples are not supported. Use data classes instead.");
  }
Пример #10
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;
  }
Пример #11
0
  /*
   * tupleLiteral
   *   : "#" "(" (((SimpleName "=")? expression){","})? ")"
   *   ;
   */
  @Deprecated // Tuples are dropped, but parsing is left to minimize surprising. This code should be
              // removed some time (in Kotlin 1.0?)
  private void parseTupleExpression() {
    assert _at(HASH);
    PsiBuilder.Marker mark = mark();

    advance(); // HASH
    advance(); // LPAR
    myBuilder.disableNewlines();
    if (!at(RPAR)) {
      while (true) {
        while (at(COMMA)) {
          advance();
        }

        if (at(IDENTIFIER) && lookahead(1) == EQ) {
          advance(); // IDENTIFIER
          advance(); // EQ
          parseExpression();
        } else {
          parseExpression();
        }

        if (!at(COMMA)) break;
        advance(); // COMMA

        if (at(RPAR)) {
          break;
        }
      }
    }
    consumeIf(RPAR);
    myBuilder.restoreNewlinesState();

    mark.error("Tuples are not supported. Use data classes instead.");
  }
 protected void errorUntilEol(String message) {
   PsiBuilder.Marker errorMarker = mark();
   advanceUntilEol();
   errorMarker.error(message);
 }
 protected void errorUntil(TokenSet tokenSet, String message) {
   PsiBuilder.Marker errorMarker = mark();
   advanceUntil(tokenSet);
   errorMarker.error(message);
 }
Пример #14
0
  public static boolean exitErrorRecordingSection(
      PsiBuilder builder_,
      int level,
      boolean result,
      boolean pinned,
      @NotNull String sectionType,
      @Nullable Parser eatMore) {
    ErrorState state = ErrorState.get(builder_);

    Frame frame = state.levelCheck.pollLast();
    int initialOffset = builder_.getCurrentOffset();
    if (frame == null || level != frame.level || !sectionType.equals(frame.section)) {
      LOG.error(
          "Unbalanced error section: got "
              + new Frame().init(initialOffset, level, sectionType, "", 0)
              + ", expected "
              + frame);
      if (frame != null) state.FRAMES.recycle(frame);
      return result;
    }
    if (sectionType == _SECTION_AND_ || sectionType == _SECTION_NOT_) {
      state.predicateCount--;
      if (sectionType == _SECTION_NOT_) state.predicateSign = !state.predicateSign;
      state.FRAMES.recycle(frame);
      return result;
    }
    if (!result
        && !pinned
        && initialOffset == frame.offset
        && state.lastExpectedVariantOffset == frame.offset
        && frame.name != null
        && state.variants.size() - frame.variantCount > 1) {
      state.clearVariants(true, frame.variantCount);
      addVariantInner(state, initialOffset, frame.name);
    }
    if (sectionType == _SECTION_RECOVER_ && !state.suppressErrors && eatMore != null) {
      state.suppressErrors = true;
      final boolean eatMoreFlagOnce = !builder_.eof() && eatMore.parse(builder_, frame.level + 1);
      final int lastErrorPos = getLastVariantOffset(state, initialOffset);
      boolean eatMoreFlag =
          eatMoreFlagOnce || frame.offset == initialOffset && lastErrorPos > frame.offset;

      final LighterASTNode latestDoneMarker =
          (pinned || result) && (state.altMode || lastErrorPos > initialOffset) && eatMoreFlagOnce
              ? builder_.getLatestDoneMarker()
              : null;
      PsiBuilder.Marker extensionMarker = null;
      IElementType extensionTokenType = null;
      if (latestDoneMarker instanceof PsiBuilder.Marker) {
        extensionMarker = ((PsiBuilder.Marker) latestDoneMarker).precede();
        extensionTokenType = latestDoneMarker.getTokenType();
        ((PsiBuilder.Marker) latestDoneMarker).drop();
      }
      // advance to the last error pos
      // skip tokens until lastErrorPos. parseAsTree might look better here...
      int parenCount = 0;
      while (eatMoreFlag && builder_.getCurrentOffset() < lastErrorPos) {
        if (state.braces != null) {
          if (builder_.getTokenType() == state.braces[0].getLeftBraceType()) parenCount++;
          else if (builder_.getTokenType() == state.braces[0].getRightBraceType()) parenCount--;
        }
        builder_.advanceLexer();
        eatMoreFlag = parenCount != 0 || eatMore.parse(builder_, frame.level + 1);
      }
      boolean errorReported = frame.errorReportedAt == initialOffset;
      if (errorReported) {
        if (eatMoreFlag) {
          builder_.advanceLexer();
          parseAsTree(state, builder_, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore);
        }
      } else if (eatMoreFlag) {
        String tokenText = builder_.getTokenText();
        String expectedText = state.getExpectedText(builder_);
        PsiBuilder.Marker mark = builder_.mark();
        builder_.advanceLexer();
        final String gotText =
            !expectedText.isEmpty() ? "got '" + tokenText + "'" : "'" + tokenText + "' unexpected";
        mark.error(expectedText + gotText);
        parseAsTree(state, builder_, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore);
        errorReported = true;
      } else if (eatMoreFlagOnce || (!result && frame.offset != builder_.getCurrentOffset())) {
        reportError(state, builder_, true);
        errorReported = true;
      }
      if (extensionMarker != null) {
        extensionMarker.done(extensionTokenType);
      }
      state.suppressErrors = false;
      if (errorReported || result) {
        state.clearVariants(true, 0);
        state.clearVariants(false, 0);
        state.lastExpectedVariantOffset = -1;
      }
      if (!result && eatMoreFlagOnce && frame.offset != builder_.getCurrentOffset()) result = true;
    } else if (!result && pinned && frame.errorReportedAt < 0) {
      // do not report if there're errors after current offset
      if (getLastVariantOffset(state, initialOffset) == initialOffset) {
        // do not force, inner recoverRoot might have skipped some tokens
        if (reportError(state, builder_, false)) {
          frame.errorReportedAt = initialOffset;
        }
      }
    }
    // propagate errorReportedAt up the stack to avoid duplicate reporting
    Frame prevFrame = state.levelCheck.isEmpty() ? null : state.levelCheck.getLast();
    if (prevFrame != null && prevFrame.errorReportedAt < frame.errorReportedAt)
      prevFrame.errorReportedAt = frame.errorReportedAt;
    state.FRAMES.recycle(frame);
    return result;
  }