Search in sources :

Example 1 with PerlVisitor

use of com.perl5.lang.perl.psi.PerlVisitor in project Perl5-IDEA by Camelcade.

the class PerlFancyMethodCallInspection method buildVisitor.

@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new PerlVisitor() {

        @Override
        public void visitMethod(@NotNull PsiPerlMethod o) {
            if (o.isObjectMethod() && o.getLastChild() instanceof PerlNamespaceElement) {
                String packageName = o.getPackageName();
                if (packageName == null) {
                    return;
                }
                PerlSubNameElement subNameElement = o.getSubNameElement();
                if (subNameElement == null) {
                    return;
                }
                String properForm = String.format("%s->%s", packageName, subNameElement.getName());
                holder.registerProblem(o, PerlBundle.message("perl.inspection.fancy.call", properForm), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new PerlFancyMethodQuickFix(properForm));
            }
        }
    };
}
Also used : PerlSubNameElement(com.perl5.lang.perl.psi.PerlSubNameElement) PsiPerlMethod(com.perl5.lang.perl.psi.PsiPerlMethod) PerlFancyMethodQuickFix(com.perl5.lang.perl.idea.quickfixes.PerlFancyMethodQuickFix) PerlNamespaceElement(com.perl5.lang.perl.psi.PerlNamespaceElement) PerlVisitor(com.perl5.lang.perl.psi.PerlVisitor) NotNull(org.jetbrains.annotations.NotNull) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with PerlVisitor

use of com.perl5.lang.perl.psi.PerlVisitor in project Perl5-IDEA by Camelcade.

the class PerlLoopControlInspection method buildVisitor.

@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
    PerlSubDefinitionElement breakDefinition = PerlBuiltInSubsService.getInstance(holder.getProject()).findSub("break");
    return new PerlVisitor() {

        @Override
        public void visitNextExpr(@NotNull PsiPerlNextExpr o) {
            processLoopsControl(o);
        }

        @Override
        public void visitRedoExpr(@NotNull PsiPerlRedoExpr o) {
            processLoopsControl(o);
        }

        @Override
        public void visitLastExpr(@NotNull PsiPerlLastExpr o) {
            processLoopsControl(o);
        }

        @Override
        public void visitContinueExpr(@NotNull PsiPerlContinueExpr o) {
            PsiElement position = o;
            boolean isInsideTheLoop = false;
            while (true) {
                PsiElement closestBlockContainer = getClosestBlockContainer(position);
                if (closestBlockContainer == null) {
                    break;
                }
                IElementType blockContainerElementType = PsiUtilCore.getElementType(closestBlockContainer);
                if (blockContainerElementType == WHEN_COMPOUND || blockContainerElementType == DEFAULT_COMPOUND) {
                    return;
                } else if (LOOPS_CONTAINERS.contains(blockContainerElementType)) {
                    isInsideTheLoop = true;
                } else if (blockContainerElementType == NAMED_BLOCK) {
                    break;
                } else if (MAP_GREP.contains(blockContainerElementType)) {
                    break;
                } else if (BLOCKS_WITH_RETURN_VALUE.contains(blockContainerElementType)) {
                    break;
                } else if (blockContainerElementType == GIVEN_COMPOUND) {
                    break;
                }
                position = closestBlockContainer;
            }
            if (isInsideTheLoop) {
                holder.registerProblem(o, PerlBundle.message("perl.inspection.loop.control.continue.instead.of.next"), new ReplaceWithExpressionQuickFix("next"));
            } else {
                problem(o, "perl.inspection.loop.control.continue");
            }
        }

        @Override
        public void visitSubNameElement(@NotNull PerlSubNameElement o) {
            PsiReference reference = o.getReference();
            if (reference == null) {
                return;
            }
            if (reference.resolve() != breakDefinition) {
                return;
            }
            PsiElement position = o;
            boolean isInsideTheLoop = false;
            while (true) {
                PsiElement closestBlockContainer = getClosestBlockContainer(position);
                if (closestBlockContainer == null) {
                    break;
                }
                IElementType blockContainerElementType = PsiUtilCore.getElementType(closestBlockContainer);
                if (LOOPS_CONTAINERS.contains(blockContainerElementType)) {
                    isInsideTheLoop = true;
                } else if (blockContainerElementType == NAMED_BLOCK) {
                    break;
                } else if (MAP_GREP.contains(blockContainerElementType)) {
                    break;
                } else if (BLOCKS_WITH_RETURN_VALUE.contains(blockContainerElementType)) {
                    break;
                } else if (blockContainerElementType == GIVEN_COMPOUND) {
                    return;
                }
                position = closestBlockContainer;
            }
            if (isInsideTheLoop) {
                holder.registerProblem(o, PerlBundle.message("perl.inspection.loop.control.break.instead.of.last"), new ReplaceWithExpressionQuickFix("last"));
            } else {
                problem(o, "perl.inspection.loop.control.break");
            }
        }

        private void problem(@NotNull PsiElement anchor, @NotNull String key, @NotNull String... args) {
            registerProblem(holder, anchor, PerlBundle.message(key, (Object[]) args));
        }

        /**
         * @return parent psi element for closest parent block element
         */
        @Nullable
        private PsiElement getClosestBlockContainer(@NotNull PsiElement position) {
            PsiPerlBlock enclosingBlock = PsiTreeUtil.getParentOfType(position, PsiPerlBlock.class);
            if (enclosingBlock == null) {
                return null;
            }
            PsiElement blockContainer = enclosingBlock.getParent();
            return PsiUtilCore.getElementType(blockContainer) == LP_CODE_BLOCK ? blockContainer.getParent() : blockContainer;
        }

        /**
         * Traversing blocks up, trying to figure out if last/next/redo are in right place.
         *
         * @param expr last/next/redo expression
         */
        private void processLoopsControl(@NotNull PsiElement expr) {
            PsiElement keyword = expr.getFirstChild();
            if (keyword == null) {
                return;
            }
            String keywordText = keyword.getText();
            // checks modifier
            PsiPerlStatementImpl containingStatement = PsiTreeUtil.getParentOfType(expr, PsiPerlStatementImpl.class);
            PsiPerlStatementModifier modifier = containingStatement == null ? null : containingStatement.getModifier();
            if (modifier instanceof PsiPerlForStatementModifier) {
                return;
            }
            // traversing up
            PsiElement position = expr;
            boolean isInsideGiven = false;
            boolean isInsideWhenOrDefault = false;
            while (true) {
                PsiElement closestBlockContainer = getClosestBlockContainer(position);
                if (closestBlockContainer == null) {
                    break;
                }
                IElementType blockContainerType = PsiUtilCore.getElementType(closestBlockContainer);
                if (LOOPS_CONTAINERS.contains(blockContainerType)) {
                    return;
                } else if (blockContainerType == NAMED_BLOCK) {
                    problem(expr, "perl.inspection.loop.control.in.named.block", keywordText);
                    return;
                } else if (MAP_GREP.contains(blockContainerType)) {
                    problem(expr, "perl.inspection.loop.control.in.map", keywordText);
                    return;
                } else if (BLOCKS_WITH_RETURN_VALUE.contains(blockContainerType)) {
                    problem(expr, "perl.inspection.loop.control.in.do", keywordText);
                    return;
                } else if (blockContainerType == GIVEN_COMPOUND) {
                    isInsideGiven = true;
                } else if (blockContainerType == WHEN_COMPOUND || blockContainerType == DEFAULT_COMPOUND) {
                    isInsideWhenOrDefault = true;
                }
                position = closestBlockContainer;
            }
            if (expr instanceof PsiPerlNextExpr && isInsideWhenOrDefault) {
                holder.registerProblem(expr, PerlBundle.message("perl.inspection.loop.control.next.instead.of.continue"), new ReplaceWithExpressionQuickFix("continue"));
            } else if (expr instanceof PsiPerlLastExpr && isInsideGiven) {
                holder.registerProblem(expr, PerlBundle.message("perl.inspection.loop.control.last.instead.of.break"), new ReplaceWithExpressionQuickFix("break"));
            } else {
                problem(expr, "perl.inspection.loop.control.outside", keywordText);
            }
        }
    };
}
Also used : PsiReference(com.intellij.psi.PsiReference) PsiPerlStatementImpl(com.perl5.lang.perl.psi.impl.PsiPerlStatementImpl) NotNull(org.jetbrains.annotations.NotNull) IElementType(com.intellij.psi.tree.IElementType) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with PerlVisitor

use of com.perl5.lang.perl.psi.PerlVisitor in project Perl5-IDEA by Camelcade.

the class PerlMultipleNamespaceDefinitionsInspection method buildVisitor.

@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new PerlVisitor() {

        @Override
        public void visitPerlNamespaceDefinitionWithIdentifier(@NotNull PerlNamespaceDefinitionWithIdentifier o) {
            Project project = o.getProject();
            String packageName = o.getPackageName();
            if (packageName != null && !PerlPackageUtil.MAIN_PACKAGE.equals(packageName) && PerlPackageUtil.getNamespaceDefinitions(project, o.getPackageName(), GlobalSearchScope.projectScope(project)).size() > 1 && o.getNameIdentifier() != null) {
                registerProblem(holder, o.getNameIdentifier(), "Multiple namespace definitions found");
            }
        }
    };
}
Also used : Project(com.intellij.openapi.project.Project) PerlVisitor(com.perl5.lang.perl.psi.PerlVisitor) NotNull(org.jetbrains.annotations.NotNull) PerlNamespaceDefinitionWithIdentifier(com.perl5.lang.perl.psi.PerlNamespaceDefinitionWithIdentifier) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with PerlVisitor

use of com.perl5.lang.perl.psi.PerlVisitor in project Perl5-IDEA by Camelcade.

the class PerlMultipleSubDeclarationsInspection method buildVisitor.

@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new PerlVisitor() {

        @Override
        public void visitSubDeclarationElement(@NotNull PerlSubDeclarationElement o) {
            Project project = o.getProject();
            String canonicalName = o.getCanonicalName();
            if (PerlSubUtil.getSubDeclarations(project, canonicalName, GlobalSearchScope.projectScope(project)).size() > 1) {
                registerProblem(holder, o.getNameIdentifier(), "Multiple subs declarations found");
            }
        }
    };
}
Also used : Project(com.intellij.openapi.project.Project) PerlVisitor(com.perl5.lang.perl.psi.PerlVisitor) PerlSubDeclarationElement(com.perl5.lang.perl.psi.PerlSubDeclarationElement) NotNull(org.jetbrains.annotations.NotNull) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with PerlVisitor

use of com.perl5.lang.perl.psi.PerlVisitor in project Perl5-IDEA by Camelcade.

the class PerlMultipleSubDefinitionsInspection method buildVisitor.

@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new PerlVisitor() {

        @Override
        public void visitPerlSubDefinitionElement(@NotNull PerlSubDefinitionElement o) {
            Project project = o.getProject();
            String name = "Sub";
            String canonicalName = o.getCanonicalName();
            if (PerlSubUtil.getSubDefinitions(project, canonicalName, GlobalSearchScope.projectScope(project)).size() > 1) {
                if (!PerlPackageUtil.isMain(o.getPackageName()) || !PerlSharedSettings.getInstance(project).SIMPLE_MAIN_RESOLUTION) {
                    registerProblem(holder, o.getNameIdentifier(), String.format("Multiple %ss definitions found", name.toLowerCase()));
                }
            }
            super.visitPerlSubDefinitionElement(o);
        }
    };
}
Also used : Project(com.intellij.openapi.project.Project) PerlVisitor(com.perl5.lang.perl.psi.PerlVisitor) NotNull(org.jetbrains.annotations.NotNull) PerlSubDefinitionElement(com.perl5.lang.perl.psi.PerlSubDefinitionElement) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

NotNull (org.jetbrains.annotations.NotNull)13 PerlVisitor (com.perl5.lang.perl.psi.PerlVisitor)12 PsiElement (com.intellij.psi.PsiElement)4 Project (com.intellij.openapi.project.Project)3 PsiReference (com.intellij.psi.PsiReference)3 PerlNamespaceDefinitionWithIdentifier (com.perl5.lang.perl.psi.PerlNamespaceDefinitionWithIdentifier)3 PerlNamespaceElement (com.perl5.lang.perl.psi.PerlNamespaceElement)3 FileType (com.intellij.openapi.fileTypes.FileType)2 PsiFile (com.intellij.psi.PsiFile)2 InjectedFileViewProvider (com.intellij.psi.impl.source.tree.injected.InjectedFileViewProvider)2 LightVirtualFile (com.intellij.testFramework.LightVirtualFile)2 PerlFileType (com.perl5.lang.perl.fileTypes.PerlFileType)2 PerlUsePackageQuickFix (com.perl5.lang.perl.idea.quickfixes.PerlUsePackageQuickFix)2 PerlSubNameElement (com.perl5.lang.perl.psi.PerlSubNameElement)2 PerlUseStatement (com.perl5.lang.perl.psi.PerlUseStatement)2 PsiPerlMethod (com.perl5.lang.perl.psi.PsiPerlMethod)2 PsiPolyVariantReference (com.intellij.psi.PsiPolyVariantReference)1 IElementType (com.intellij.psi.tree.IElementType)1 PerlStrictProvider (com.perl5.lang.perl.extensions.packageprocessor.PerlStrictProvider)1 PerlWarningsProvider (com.perl5.lang.perl.extensions.packageprocessor.PerlWarningsProvider)1