Package ro.redeul.google.go.inspection

Source Code of ro.redeul.google.go.inspection.InspectionUtil

package ro.redeul.google.go.inspection;

import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import ro.redeul.google.go.lang.parser.GoElementTypes;
import ro.redeul.google.go.lang.psi.declarations.GoVarDeclaration;
import ro.redeul.google.go.lang.psi.expressions.GoExpr;
import ro.redeul.google.go.lang.psi.expressions.GoUnaryExpression;
import ro.redeul.google.go.lang.psi.expressions.binary.GoBinaryExpression;
import ro.redeul.google.go.lang.psi.expressions.literals.GoLiteralIdentifier;
import ro.redeul.google.go.lang.psi.expressions.primary.GoCallOrConvExpression;
import ro.redeul.google.go.lang.psi.expressions.primary.GoLiteralExpression;
import ro.redeul.google.go.lang.psi.expressions.primary.GoParenthesisedExpression;
import ro.redeul.google.go.lang.psi.expressions.primary.GoSelectorExpression;
import ro.redeul.google.go.lang.psi.expressions.primary.GoTypeAssertionExpression;
import ro.redeul.google.go.lang.psi.toplevel.GoFunctionDeclaration;
import ro.redeul.google.go.lang.psi.toplevel.GoFunctionParameter;

import static ro.redeul.google.go.lang.psi.utils.GoExpressionUtils.resolveToFunctionDeclaration;
import static ro.redeul.google.go.lang.psi.utils.GoPsiUtils.isNodeOfType;

public class InspectionUtil {
    public static TextRange getProblemRange(ProblemDescriptor pd) {
        int start = pd.getStartElement().getTextOffset();
        int end = pd.getEndElement().getTextOffset() + pd.getEndElement()
                .getTextLength();
        return new TextRange(start, end);
    }

    public static final int UNKNOWN_COUNT = -1;
    public static final int VARIADIC_COUNT = -2;

    public static int getExpressionResultCount(GoExpr call) {
        if (call instanceof GoLiteralExpression
                || call instanceof GoBinaryExpression
                || (call instanceof GoUnaryExpression && ((GoUnaryExpression) call).getUnaryOp() != GoUnaryExpression.Op.Channel)
                || call instanceof GoParenthesisedExpression
                || call instanceof GoSelectorExpression
                ) {
            return 1;
        } else if (call instanceof GoTypeAssertionExpression) {
            return getTypeAssertionResultCount(
                    (GoTypeAssertionExpression) call);
        } else if (call instanceof GoCallOrConvExpression) {
            return getFunctionResultCount((GoCallOrConvExpression) call);
        }

        return UNKNOWN_COUNT;
    }

    private static int getTypeAssertionResultCount(GoTypeAssertionExpression expression) {
        PsiElement parent = expression.getParent();
        if (isNodeOfType(parent, GoElementTypes.ASSIGN_STATEMENT)) {
            // TODO: get expressions and identifiers of assign statement
            return UNKNOWN_COUNT;
        }

        if (!(parent instanceof GoVarDeclaration)) {
            return 1;
        }

        GoLiteralIdentifier[] identifiers = ((GoVarDeclaration) parent).getIdentifiers();
        GoExpr[] expressions = ((GoVarDeclaration) parent).getExpressions();
        // if the type assertion is the only expression, and there are two variables.
        // The result of the type assertion is a pair of values with types (T, bool)
        if (identifiers.length == 2 && expressions.length == 1) {
            return 2;
        }

        return 1;
    }

    private static int getFunctionResultCount(GoCallOrConvExpression call) {
        GoFunctionDeclaration function = resolveToFunctionDeclaration(call);
        return function == null ? UNKNOWN_COUNT : getFunctionResultCount(function);
    }

    public static int getFunctionResultCount(GoFunctionDeclaration function) {
        int count = 0;
        for (GoFunctionParameter p : function.getResults()) {
            count += Math.max(p.getIdentifiers().length, 1);
        }
        return count;
    }


    public static int getFunctionParameterCount(GoCallOrConvExpression call) {
        GoFunctionDeclaration function = resolveToFunctionDeclaration(call);
        if (function == null) {
            return UNKNOWN_COUNT;
        }

        int count = 0;
        for (GoFunctionParameter p : function.getParameters()) {
            count += Math.max(p.getIdentifiers().length, 1);
            if (p.isVariadic()) {
                return VARIADIC_COUNT;
            }
        }
        return count;
    }
}
TOP

Related Classes of ro.redeul.google.go.inspection.InspectionUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.