All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.ExpressionStatement Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition groovy-psi library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions;

import com.intellij.lang.PsiBuilder;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.parser.GroovyParser;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.blocks.OpenOrClosableBlock;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arguments.CommandArguments;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arithmetic.PathExpression;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arithmetic.UnaryExpressionNotPlusMinus;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.primary.PrimaryExpression;
import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;

/**
 * Main classdef for any general expression parsing
 *
 * http://svn.codehaus.org/groovy/trunk/groovy/groovy-core/src/test/gls/syntax/Gep3Test.groovy
 * @author ilyas
 */
public class ExpressionStatement {

  private static IElementType parseExpressionStatement(PsiBuilder builder, GroovyParser parser) {
    if (checkForTypeCast(builder, parser)) return GroovyElementTypes.CAST_EXPRESSION;
    PsiBuilder.Marker marker = builder.mark();
    final PathExpression.Result result = PathExpression.parsePathExprQualifierForExprStatement(builder, parser);
    if (result != PathExpression.Result.WRONG_WAY &&
        !TokenSets.SEPARATORS.contains(builder.getTokenType()) &&
        !TokenSets.BINARY_OP_SET.contains(builder.getTokenType()) &&
        !TokenSets.POSTFIX_UNARY_OP_SET.contains(builder.getTokenType())) {
      if (result == PathExpression.Result.METHOD_CALL) {
        marker.drop();
        return GroovyElementTypes.PATH_METHOD_CALL;
      }

      if (result == PathExpression.Result.LITERAL) {
        final PsiBuilder.Marker newMarker = marker.precede();
        marker.rollbackTo();
        marker = newMarker;
        PrimaryExpression.parsePrimaryExpression(builder, parser, true);
      }
      if (CommandArguments.parseCommandArguments(builder, parser)) {
        marker.done(GroovyElementTypes.CALL_EXPRESSION);
        return GroovyElementTypes.CALL_EXPRESSION;
      }
    }
    marker.drop();
    return GroovyElementTypes.WRONGWAY;
  }

  private static boolean checkForTypeCast(PsiBuilder builder, GroovyParser parser) {
    return UnaryExpressionNotPlusMinus.parse(builder, parser, false);
  }

  /**
   * Use for parse expressions in Argument position
   *
   * @param builder - Given builder
   * @return type of parsing result
   */
  public static boolean argParse(PsiBuilder builder, GroovyParser parser) {
    return AssignmentExpression.parse(builder, parser);
  }

  enum Result {
    WRONG_WAY, EXPR_STATEMENT, EXPRESSION
  }

  public static Result parse(PsiBuilder builder, GroovyParser parser) {
    PsiBuilder.Marker marker = builder.mark();

    final IElementType result = parseExpressionStatement(builder, parser);
    if (result != GroovyElementTypes.CALL_EXPRESSION && result != GroovyElementTypes.PATH_METHOD_CALL) {
      marker.drop();
      return result == GroovyElementTypes.WRONGWAY ? Result.WRONG_WAY : Result.EXPRESSION;
    }

    boolean isExprStatement = result == GroovyElementTypes.CALL_EXPRESSION;

    while (true) {
      boolean nameParsed = namePartParse(builder, parser) == GroovyElementTypes.REFERENCE_EXPRESSION;

      PsiBuilder.Marker exprStatement;

      if (nameParsed) {
        exprStatement = marker.precede();
        marker.done(GroovyElementTypes.REFERENCE_EXPRESSION);
      }
      else {
        exprStatement = marker;
      }

      if (builder.getTokenType() == GroovyTokenTypes.mLPAREN) {
        PrimaryExpression.methodCallArgsParse(builder, parser);
        exprStatement.done(GroovyElementTypes.PATH_METHOD_CALL);
      }
      else if (GroovyTokenTypes.mLBRACK.equals(builder.getTokenType()) &&
               !ParserUtils.lookAhead(builder, GroovyTokenTypes.mLBRACK, GroovyTokenTypes.mCOLON) &&
               !ParserUtils.lookAhead(builder, GroovyTokenTypes.mLBRACK, GroovyTokenTypes.mNLS, GroovyTokenTypes.mCOLON)) {
        PathExpression.indexPropertyArgsParse(builder, parser);
        exprStatement.done(GroovyElementTypes.PATH_INDEX_PROPERTY);
        if (GroovyTokenTypes.mLPAREN.equals(builder.getTokenType())) {
          PrimaryExpression.methodCallArgsParse(builder, parser);
        }
        else if (GroovyTokenTypes.mLCURLY.equals(builder.getTokenType())) {
          PsiBuilder.Marker argsMarker = builder.mark();
          argsMarker.done(GroovyElementTypes.ARGUMENTS);
        }
        while (GroovyTokenTypes.mLCURLY.equals(builder.getTokenType())) {
          OpenOrClosableBlock.parseClosableBlock(builder, parser);
        }
        exprStatement = exprStatement.precede();
        exprStatement.done(GroovyElementTypes.PATH_METHOD_CALL);
      }
      else if (nameParsed && CommandArguments.parseCommandArguments(builder, parser)) {
        isExprStatement = true;
        exprStatement.done(GroovyElementTypes.CALL_EXPRESSION);
      }
      else {
        exprStatement.drop();
        break;
      }

      marker = exprStatement.precede();
    }

    return isExprStatement ? Result.EXPR_STATEMENT : Result.EXPRESSION;
  }

  private static GroovyElementType namePartParse(PsiBuilder builder, GroovyParser parser) {
    if (TokenSets.BINARY_OP_SET.contains(builder.getTokenType())) return GroovyElementTypes.WRONGWAY;
    if (TokenSets.KEYWORDS.contains(builder.getTokenType())) return GroovyElementTypes.WRONGWAY;
    final GroovyElementType type = PathExpression.namePartParse(builder, parser);
    if (type == GroovyElementTypes.WRONGWAY && TokenSets.NUMBERS.contains(builder.getTokenType())) {
      builder.advanceLexer();
      return GroovyElementTypes.REFERENCE_EXPRESSION;
    }
    return type;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy