Package ro.redeul.google.go.findUsages

Source Code of ro.redeul.google.go.findUsages.GoVariableUsageStatVisitor2

package ro.redeul.google.go.findUsages;

import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.psi.tree.TokenSet;
import ro.redeul.google.go.GoBundle;
import ro.redeul.google.go.inspection.InspectionResult;
import ro.redeul.google.go.inspection.fix.RemoveVariableFix;
import ro.redeul.google.go.lang.parser.GoElementTypes;
import ro.redeul.google.go.lang.psi.GoFile;
import ro.redeul.google.go.lang.psi.GoPsiElement;
import ro.redeul.google.go.lang.psi.declarations.GoConstDeclaration;
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.literals.GoLiteralIdentifier;
import ro.redeul.google.go.lang.psi.expressions.primary.GoLiteralExpression;
import ro.redeul.google.go.lang.psi.impl.types.GoPsiTypeFunctionImpl;
import ro.redeul.google.go.lang.psi.processors.GoNamesUtil;
import ro.redeul.google.go.lang.psi.statements.GoShortVarDeclaration;
import ro.redeul.google.go.lang.psi.toplevel.GoFunctionDeclaration;
import ro.redeul.google.go.lang.psi.toplevel.GoFunctionParameter;
import ro.redeul.google.go.lang.psi.toplevel.GoMethodDeclaration;
import ro.redeul.google.go.lang.psi.types.GoPsiTypeInterface;
import ro.redeul.google.go.lang.psi.visitors.GoRecursiveElementVisitor;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import static com.intellij.patterns.PlatformPatterns.psiElement;
import static ro.redeul.google.go.lang.psi.patterns.GoElementPatterns.*;
import static ro.redeul.google.go.lang.psi.utils.GoPsiUtils.resolveSafely;

public class GoVariableUsageStatVisitor2 extends GoRecursiveElementVisitor {

    private static final TokenSet NEW_SCOPE_STATEMENT = TokenSet.create(
        GoElementTypes.BLOCK_STATEMENT,
        GoElementTypes.IF_STATEMENT,
        GoElementTypes.FOR_WITH_CLAUSES_STATEMENT,
        GoElementTypes.FOR_WITH_CONDITION_STATEMENT,
        GoElementTypes.FOR_WITH_RANGE_STATEMENT,
        GoElementTypes.SWITCH_EXPR_STATEMENT,
        GoElementTypes.SWITCH_TYPE_STATEMENT,
        GoElementTypes.SWITCH_EXPR_CASE,
        GoElementTypes.SELECT_STATEMENT,
        GoElementTypes.SELECT_COMM_CLAUSE_RECV,
        GoElementTypes.SELECT_COMM_CLAUSE_SEND,
        GoElementTypes.SELECT_COMM_CLAUSE_DEFAULT
    );

    private final InspectionResult result;

    public GoVariableUsageStatVisitor2(InspectionResult result) {
        this.result = result;
    }

    @Override
    public void visitFile(GoFile file) {
        visitElement(file);

        for (GoPsiElement usage : usages) {
            declarations.remove(usage);
        }

        for (GoPsiElement declaration : declarations) {

            if (psiElement(GoLiteralIdentifier.class).accepts(declaration)) {
                GoLiteralIdentifier ident = (GoLiteralIdentifier) declaration;

                if (ident.isIota() || ident.isBlank())
                    continue;

                if (GLOBAL_CONST_DECL.accepts(ident) ||
                    GLOBAL_VAR_DECL.accepts(ident)) {
                    if (GoNamesUtil.isExported(ident.getName())) {
                        continue;
                    }

                    if (GLOBAL_CONST_DECL.accepts(ident)) {
                        result.addProblem(declaration,
                                          GoBundle.message(
                                              "error.constant.not.used",
                                              declaration.getText()),
                                          ProblemHighlightType.LIKE_UNUSED_SYMBOL,
                                          new RemoveVariableFix());
                    } else {
                        result.addProblem(declaration,
                                          GoBundle.message(
                                              "error.variable.not.used",
                                              declaration.getText()),
                                          ProblemHighlightType.LIKE_UNUSED_SYMBOL,
                                          new RemoveVariableFix());
                    }
                    continue;
                }
            }

            if (declaration.getParent().getParent().getParent() instanceof GoPsiTypeFunctionImpl) {
                continue;
            }

            if (PARAMETER_DECLARATION.accepts(declaration)) {
                result.addProblem(declaration,
                                  GoBundle.message("error.parameter.not.used",
                                                   declaration.getText()),
                                  ProblemHighlightType.WEAK_WARNING);
            } else if (CONST_DECLARATION.accepts(declaration)) {
                result.addProblem(declaration,
                                  GoBundle.message("error.constant.not.used",
                                                   declaration.getText()),
                                  ProblemHighlightType.ERROR,
                                  new RemoveVariableFix());
            } else {
                result.addProblem(declaration,
                                  GoBundle.message("error.variable.not.used",
                                                   declaration.getText()),
                                  ProblemHighlightType.ERROR,
                                  new RemoveVariableFix());
            }
        }
    }

    private final Set<GoPsiElement> declarations = new HashSet<GoPsiElement>();
    private final Set<GoPsiElement> usages = new HashSet<GoPsiElement>();

    @Override
    public void visitConstDeclaration(GoConstDeclaration declaration) {
        Collections.addAll(declarations, declaration.getIdentifiers());
        for (GoExpr goExpr : declaration.getExpressions()) {
            goExpr.accept(this);
        }
    }

    @Override
    public void visitVarDeclaration(GoVarDeclaration declaration) {
        Collections.addAll(declarations, declaration.getIdentifiers());
        for (GoExpr goExpr : declaration.getExpressions()) {
            goExpr.accept(this);
        }
    }

    @Override
    public void visitShortVarDeclaration(GoShortVarDeclaration declaration) {
        GoLiteralIdentifier[] identifiers = declaration.getIdentifiers();

        for (GoLiteralIdentifier identifier : identifiers) {
            GoLiteralIdentifier definition = resolveSafely(identifier,
                                                           GoLiteralIdentifier.class);
            if (definition == null) {
                declarations.add(identifier);
            } else {
                usages.add(definition);
            }
        }

        for (GoExpr goExpr : declaration.getExpressions()) {
            goExpr.accept(this);
        }
    }

    @Override
    public void visitFunctionParameter(GoFunctionParameter parameter) {
        Collections.addAll(declarations, parameter.getIdentifiers());
    }

    @Override
    public void visitLiteralExpression(GoLiteralExpression expression) {
        GoPsiElement psiElement = resolveSafely(expression, GoPsiElement.class);
        if (psiElement != null) {
            usages.add(psiElement);
        } else {
            visitElement(expression);
        }
    }

    @Override
    public void visitLiteralIdentifier(GoLiteralIdentifier identifier) {
        GoPsiElement psiElement = resolveSafely(identifier, GoPsiElement.class);
        if (psiElement != null) {
            usages.add(psiElement);
        }
    }

    @Override
    public void visitFunctionDeclaration(GoFunctionDeclaration declaration) {
        for (GoFunctionParameter parameter : declaration.getParameters()) {
            parameter.accept(this);
        }

        if (declaration.getBlock() != null)
            declaration.getBlock().accept(this);
    }

    @Override
    public void visitMethodDeclaration(GoMethodDeclaration declaration) {
        declaration.getMethodReceiver().accept(this);

        visitFunctionDeclaration(declaration);
    }

    @Override
    public void visitInterfaceType(GoPsiTypeInterface type) {
        // dont :)
    }
}
TOP

Related Classes of ro.redeul.google.go.findUsages.GoVariableUsageStatVisitor2

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.