Package ro.redeul.google.go.intentions.statements

Source Code of ro.redeul.google.go.intentions.statements.CheckErrorIntention

package ro.redeul.google.go.intentions.statements;

import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiWhiteSpace;
import org.jetbrains.annotations.NotNull;
import ro.redeul.google.go.editor.TemplateUtil;
import ro.redeul.google.go.intentions.Intention;
import ro.redeul.google.go.intentions.IntentionExecutionException;
import ro.redeul.google.go.lang.psi.expressions.GoExpr;
import ro.redeul.google.go.lang.psi.statements.GoExpressionStatement;
import ro.redeul.google.go.lang.psi.types.GoPsiType;
import ro.redeul.google.go.lang.psi.types.GoPsiTypeName;
import ro.redeul.google.go.lang.psi.typing.GoType;
import ro.redeul.google.go.lang.psi.typing.GoTypePrimitive;
import ro.redeul.google.go.lang.psi.typing.GoTypePsiBacked;
import ro.redeul.google.go.lang.psi.typing.GoTypes;
import ro.redeul.google.go.lang.psi.typing.TypeVisitor;
import ro.redeul.google.go.lang.psi.typing.UpdatingTypeVisitor;
import ro.redeul.google.go.lang.psi.utils.GoTypeUtils;
import ro.redeul.google.go.util.GoUtil;

import java.util.ArrayList;
import java.util.List;

import static ro.redeul.google.go.lang.psi.utils.GoPsiUtils.findParentOfType;

public class CheckErrorIntention extends Intention {

    protected GoExpressionStatement statement;
    protected GoExpr expr;

    @Override
    protected boolean satisfiedBy(PsiElement element) {

        PsiElement node = element;
        if (node == null) return false;

        if (node instanceof PsiWhiteSpace)
            node = node.getPrevSibling();

        statement = findParentOfType(node, GoExpressionStatement.class);
        if (statement == null) return false;

        expr = statement.getExpression();
        if (expr == null) return false;

        for (GoType type : expr.getType()) {
            if (type == null) continue;
            GoType underlyingType = type.underlyingType();
            return underlyingType.accept(new TypeVisitor<Boolean>(false) {
                @Override
                public Boolean visitPrimitive(GoTypePrimitive type) {
                    return type.getType() == GoTypes.Builtin.Error;
                }
            });
        }

        return false;
    }

    @Override
    protected void processIntention(@NotNull PsiElement element, Editor editor) throws IntentionExecutionException {
        TextRange textRange = statement.getTextRange();

        StringBuilder varListString = new StringBuilder();
        StringBuilder checkString = new StringBuilder();
        List<String> varNames = new ArrayList<String>();


        GoType[] types = expr.getType();

        int errorVarIndex = -1;
        int varIndex = 0;
        boolean needsComma = false;
        for (GoType type : types) {
            if ( type == null)
                continue;

            if ( needsComma )
                varListString.append(", ");
            else
                needsComma = true;

            String templateVarName = String.format("$v%d$", varIndex++);
            varListString.append(templateVarName);
            GoType underlyingType = type.underlyingType();
            if ( isErrorType(type.underlyingType()) ) {
                errorVarIndex++;
                String errVarName = findVarName(expr, errorVarIndex);
                if (errorVarIndex > 0) {
                    checkString.append(" || ");
                }

                varNames.add(errVarName);
                checkString.append(templateVarName).append(" != nil");
            } else {
                varNames.add("_");
            }
        }

        if (types.length <= 1)
            varNames.set(0, expr.getText());

        StringBuilder template = new StringBuilder();

        template.append("if ");
        if ( types.length > 1 ) {
            template.append(varListString).append(":=").append(expr.getText()).append(';');
        } else {
            varNames.set(0, expr.getText());
        }

        String bodyTemplate = String.format("\n$v%d$$END$\n}", varIndex);
        varNames.add("//TODO: Handle error(s)");
        template
                .append(checkString)
                .append("{")
                .append(bodyTemplate);

        //varNames.add("panic(\"Unhandled error!\")");
        TemplateUtil.runTemplate(editor, textRange, varNames, TemplateUtil.createTemplate(template.toString()));
    }

    private String findVarName(GoExpr expr, int varIndex) {
        return String.format("err%s", varIndex == 0 ? "" : varIndex - 1);
    }

    private boolean isErrorType(GoType type) {
        return type != null &&
                type instanceof GoTypePrimitive &&
                ((GoTypePrimitive) type).getType() == GoTypes.Builtin.Error;
    }
}
TOP

Related Classes of ro.redeul.google.go.intentions.statements.CheckErrorIntention

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.