Search in sources :

Example 51 with PsiElement

use of com.intellij.psi.PsiElement in project go-lang-idea-plugin by go-lang-plugin-org.

the class GoAssignmentNilWithoutExplicitTypeInspection method buildGoVisitor.

@NotNull
@Override
protected GoVisitor buildGoVisitor(@NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
    return new GoVisitor() {

        @Override
        public void visitVarDeclaration(@NotNull GoVarDeclaration o) {
            for (GoVarSpec spec : o.getVarSpecList()) {
                checkVar(spec);
            }
        }

        @Override
        public void visitShortVarDeclaration(@NotNull GoShortVarDeclaration o) {
            checkVar(o);
        }

        @Override
        public void visitConstDeclaration(@NotNull GoConstDeclaration o) {
            for (GoConstSpec spec : o.getConstSpecList()) {
                checkConst(spec);
            }
        }

        private void checkVar(@NotNull GoVarSpec spec) {
            if (spec.getType() != null)
                return;
            checkExpressions(spec.getRightExpressionsList());
        }

        private void checkConst(@NotNull GoConstSpec spec) {
            if (spec.getType() != null)
                return;
            checkExpressions(spec.getExpressionList());
        }

        private void checkExpressions(@NotNull List<GoExpression> expressions) {
            for (GoExpression expr : expressions) {
                if (expr instanceof GoReferenceExpressionImpl) {
                    GoReferenceExpressionImpl ref = (GoReferenceExpressionImpl) expr;
                    PsiElement resolve = ref.resolve();
                    if (ref.getIdentifier().textMatches(GoConstants.NIL) && resolve != null && GoPsiImplUtil.builtin(resolve)) {
                        holder.registerProblem(expr, "Cannot assign nil without explicit type", GENERIC_ERROR_OR_WARNING);
                    }
                }
            }
        }
    };
}
Also used : GoReferenceExpressionImpl(com.goide.psi.impl.GoReferenceExpressionImpl) List(java.util.List) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 52 with PsiElement

use of com.intellij.psi.PsiElement in project go-lang-idea-plugin by go-lang-plugin-org.

the class GoAssignmentToReceiverInspection method buildGoVisitor.

@NotNull
@Override
protected GoVisitor buildGoVisitor(@NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
    return new GoVisitor() {

        @Override
        public void visitReferenceExpression(@NotNull GoReferenceExpression o) {
            super.visitReferenceExpression(o);
            if (o.getReadWriteAccess() == ReadWriteAccessDetector.Access.Write) {
                PsiElement resolve = o.resolve();
                if (resolve instanceof GoReceiver) {
                    String message = "Assignment to method receiver doesn't propagate to other calls";
                    if (((GoReceiver) resolve).getType() instanceof GoPointerType) {
                        if (o.getParent() instanceof GoUnaryExpr) {
                            GoUnaryExpr p = (GoUnaryExpr) o.getParent();
                            if (p.getMul() != null) {
                                // pointer dereference
                                return;
                            }
                        }
                        message = "Assignment to method receiver propagates only to callees but not to callers";
                    }
                    holder.registerProblem(o, message, WEAK_WARNING);
                }
            }
        }
    };
}
Also used : GoUnaryExpr(com.goide.psi.GoUnaryExpr) GoPointerType(com.goide.psi.GoPointerType) GoReceiver(com.goide.psi.GoReceiver) GoReferenceExpression(com.goide.psi.GoReferenceExpression) NotNull(org.jetbrains.annotations.NotNull) GoVisitor(com.goide.psi.GoVisitor) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 53 with PsiElement

use of com.intellij.psi.PsiElement in project go-lang-idea-plugin by go-lang-plugin-org.

the class GoBoolExpressionsInspection method buildGoVisitor.

@NotNull
@Override
protected GoVisitor buildGoVisitor(@NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
    return new GoVisitor() {

        @Override
        public void visitAndExpr(@NotNull GoAndExpr o) {
            visitExpr(o, true);
        }

        @Override
        public void visitOrExpr(@NotNull GoOrExpr o) {
            visitExpr(o, false);
        }

        private void visitExpr(GoBinaryExpr o, boolean and) {
            if (!isTopmostOperationOfType(o, and))
                return;
            List<GoExpression> elements = collect(o, and);
            for (int i = 0; i < elements.size(); i++) {
                GoExpression l = elements.get(i);
                if (l instanceof GoReferenceExpression && (l.textMatches("true") || l.textMatches("false")) && GoPsiImplUtil.builtin(((GoReferenceExpression) l).resolve())) {
                    registerProblem(o, holder);
                    return;
                }
                for (int j = i + 1; j < elements.size(); j++) {
                    ProgressManager.checkCanceled();
                    GoExpression r = elements.get(j);
                    if (isEqualsWithNot(l, r) || isEqualsWithNot(r, l) || GoExpressionUtil.identical(l, r)) {
                        registerProblem(o, holder);
                        return;
                    }
                // todo expr evaluating! x != c1 || x != c2 (c1, c2 const, c1 != c2)
                }
            }
        }

        private boolean isTopmostOperationOfType(GoBinaryExpr o, boolean isAndType) {
            PsiElement parent = PsiTreeUtil.skipParentsOfType(o, GoParenthesesExpr.class);
            return !(parent instanceof GoBinaryExpr) || !isSameOp((GoExpression) parent, isAndType);
        }
    };
}
Also used : NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 54 with PsiElement

use of com.intellij.psi.PsiElement in project go-lang-idea-plugin by go-lang-plugin-org.

the class GoDuplicateFunctionOrMethodInspection method buildGoVisitor.

@NotNull
@Override
protected GoVisitor buildGoVisitor(@NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
    return new GoVisitor() {

        @Override
        public void visitMethodDeclaration(@NotNull GoMethodDeclaration method) {
            if (method.isBlank())
                return;
            String methodName = method.getName();
            if (methodName == null)
                return;
            String typeText = GoMethodDeclarationStubElementType.calcTypeText(method);
            if (typeText == null)
                return;
            GoFile file = method.getContainingFile();
            GlobalSearchScope scope = GoPackageUtil.packageScope(file);
            IdFilter idFilter = GoIdFilter.getFilesFilter(scope);
            Module module = ModuleUtilCore.findModuleForPsiElement(file);
            String key = file.getPackageName() + "." + typeText;
            GoMethodIndex.process(key, file.getProject(), scope, idFilter, declaration -> {
                ProgressManager.checkCanceled();
                if (!method.isEquivalentTo(declaration)) {
                    if (Comparing.equal(declaration.getName(), methodName) && GoPsiImplUtil.allowed(declaration.getContainingFile(), file, module)) {
                        PsiElement identifier = method.getNameIdentifier();
                        holder.registerProblem(identifier == null ? method : identifier, "Duplicate method name");
                        return false;
                    }
                }
                return true;
            });
        }

        @Override
        public void visitFunctionDeclaration(@NotNull GoFunctionDeclaration func) {
            if (func.isBlank())
                return;
            String funcName = func.getName();
            if (funcName == null)
                return;
            if (INIT.equals(funcName) && zeroArity(func))
                return;
            GoFile file = func.getContainingFile();
            boolean isMainFunction = MAIN.equals(funcName) && MAIN.equals(file.getPackageName()) && zeroArity(func);
            Module module = ModuleUtilCore.findModuleForPsiElement(file);
            GlobalSearchScope scope = GoPackageUtil.packageScope(file);
            IdFilter idFilter = GoIdFilter.getFilesFilter(scope);
            GoFunctionIndex.process(funcName, file.getProject(), scope, idFilter, declaration -> {
                ProgressManager.checkCanceled();
                if (!func.isEquivalentTo(declaration) && GoPsiImplUtil.allowed(declaration.getContainingFile(), file, module)) {
                    if (!isMainFunction || Comparing.equal(declaration.getContainingFile(), file)) {
                        PsiElement identifier = func.getNameIdentifier();
                        holder.registerProblem(identifier == null ? func : identifier, "Duplicate function name");
                        return false;
                    }
                }
                return true;
            });
        }
    };
}
Also used : IdFilter(com.intellij.util.indexing.IdFilter) GoIdFilter(com.goide.stubs.index.GoIdFilter) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) Module(com.intellij.openapi.module.Module) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 55 with PsiElement

use of com.intellij.psi.PsiElement in project go-lang-idea-plugin by go-lang-plugin-org.

the class GoFunctionCallInspection method buildGoVisitor.

@NotNull
@Override
protected GoVisitor buildGoVisitor(@NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
    return new GoVisitor() {

        @Override
        public void visitCallExpr(@NotNull GoCallExpr o) {
            super.visitCallExpr(o);
            PsiElement resolve = GoPsiImplUtil.resolveCallRaw(o);
            GoExpression expression = o.getExpression();
            if (resolve != null && expression instanceof GoReferenceExpression) {
                List<GoExpression> list = o.getArgumentList().getExpressionList();
                int actualSize = list.size();
                if (resolve instanceof GoTypeSpec && actualSize != 1) {
                    String message = String.format("%sto conversion to %s: %s.", actualSize == 0 ? "Missing argument " : "Too many arguments ", expression.getText(), o.getText());
                    holder.registerProblem(o, message);
                } else if (resolve instanceof GoSignatureOwner) {
                    GoSignature signature = ((GoSignatureOwner) resolve).getSignature();
                    if (signature == null)
                        return;
                    int expectedSize = 0;
                    GoParameters parameters = signature.getParameters();
                    for (GoParameterDeclaration declaration : parameters.getParameterDeclarationList()) {
                        if (declaration.isVariadic() && actualSize >= expectedSize)
                            return;
                        int size = declaration.getParamDefinitionList().size();
                        expectedSize += size == 0 ? 1 : size;
                    }
                    if (actualSize == 1) {
                        GoExpression first = ContainerUtil.getFirstItem(list);
                        GoSignatureOwner firstResolve = GoPsiImplUtil.resolveCall(first);
                        if (firstResolve != null) {
                            actualSize = GoInspectionUtil.getFunctionResultCount(firstResolve);
                        }
                    }
                    GoReferenceExpression qualifier = ((GoReferenceExpression) expression).getQualifier();
                    boolean isMethodExpr = qualifier != null && qualifier.resolve() instanceof GoTypeSpec;
                    // todo: a temp workaround for method specs
                    if (isMethodExpr)
                        actualSize -= 1;
                    if (actualSize == expectedSize)
                        return;
                    String tail = " arguments in call to " + expression.getText();
                    holder.registerProblem(o.getArgumentList(), (actualSize > expectedSize ? "too many" : "not enough") + tail);
                }
            }
        }
    };
}
Also used : NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

PsiElement (com.intellij.psi.PsiElement)3198 Nullable (org.jetbrains.annotations.Nullable)493 PsiFile (com.intellij.psi.PsiFile)474 NotNull (org.jetbrains.annotations.NotNull)442 TextRange (com.intellij.openapi.util.TextRange)239 PsiReference (com.intellij.psi.PsiReference)227 Project (com.intellij.openapi.project.Project)222 VirtualFile (com.intellij.openapi.vfs.VirtualFile)210 ArrayList (java.util.ArrayList)195 ASTNode (com.intellij.lang.ASTNode)142 XmlTag (com.intellij.psi.xml.XmlTag)134 PsiClass (com.intellij.psi.PsiClass)115 Editor (com.intellij.openapi.editor.Editor)112 Document (com.intellij.openapi.editor.Document)109 PsiWhiteSpace (com.intellij.psi.PsiWhiteSpace)85 PsiDirectory (com.intellij.psi.PsiDirectory)80 IElementType (com.intellij.psi.tree.IElementType)78 Module (com.intellij.openapi.module.Module)77 PsiMethod (com.intellij.psi.PsiMethod)73 UsageInfo (com.intellij.usageView.UsageInfo)70