Search in sources :

Example 1 with PerlImplicitVariableDeclaration

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

the class PerlVariableShadowingInspection method checkDeclaration.

@Override
public void checkDeclaration(ProblemsHolder holder, PerlVariableDeclarationElement variableDeclarationWrapper) {
    PerlVariable variable = variableDeclarationWrapper.getVariable();
    PsiElement declarationContainer = variableDeclarationWrapper.getParent();
    if (variable != null && !(declarationContainer instanceof PsiPerlVariableDeclarationLocal)) {
        PerlVariableDeclarationElement lexicalDeclaration = PerlResolveUtil.getLexicalDeclaration(variable);
        if (lexicalDeclaration instanceof PerlBuiltInVariable) {
            registerProblem(holder, variable, PerlBundle.message("perl.inspection.shadows.builtin", lexicalDeclaration.getVariable().getLineNumber()));
        } else if (lexicalDeclaration instanceof PerlImplicitVariableDeclaration) {
            registerProblem(holder, variable, PerlBundle.message("perl.inspection.shadows.implicit", lexicalDeclaration.getVariable().getLineNumber()));
        } else if (lexicalDeclaration != null) {
            registerProblem(holder, variable, PerlBundle.message("perl.inspection.shadows.other", lexicalDeclaration.getVariable().getLineNumber()));
        }
    }
}
Also used : PsiPerlVariableDeclarationLocal(com.perl5.lang.perl.psi.PsiPerlVariableDeclarationLocal) PerlBuiltInVariable(com.perl5.lang.perl.psi.impl.PerlBuiltInVariable) PerlVariableDeclarationElement(com.perl5.lang.perl.psi.PerlVariableDeclarationElement) PerlVariable(com.perl5.lang.perl.psi.PerlVariable) PerlImplicitVariableDeclaration(com.perl5.lang.perl.psi.impl.PerlImplicitVariableDeclaration) PsiElement(com.intellij.psi.PsiElement)

Example 2 with PerlImplicitVariableDeclaration

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

the class PerlVariableMixin method getVariableTypeHeavy.

@Nullable
private String getVariableTypeHeavy() {
    if (this instanceof PsiPerlScalarVariable) {
        // System.err.println("Guessing type for " + getText() + " at " + getTextOffset());
        PerlVariableNameElement variableNameElement = getVariableNameElement();
        if (variableNameElement != null) {
            // find lexicaly visible declaration and check type
            final PerlVariableDeclarationElement declarationWrapper = getLexicalDeclaration();
            if (declarationWrapper != null) {
                if (declarationWrapper instanceof PerlImplicitVariableDeclaration) {
                    return ((PerlImplicitVariableDeclaration) declarationWrapper).getVariableClass();
                }
                if (declarationWrapper.isInvocantDeclaration() || declarationWrapper.isSelf()) {
                    PerlSelfHinter selfHinter = PsiTreeUtil.getParentOfType(declarationWrapper, PerlSelfHinter.class);
                    if (selfHinter != null) {
                        return selfHinter.getSelfNamespace();
                    }
                    return PerlPackageUtil.getContextPackageName(declarationWrapper);
                }
                // check explicit type in declaration
                String declarationPackageName = declarationWrapper.getDeclaredType();
                if (declarationPackageName != null) {
                    assert !declarationPackageName.equals("");
                    return declarationPackageName;
                }
                // check assignment around declaration
                PerlVariableDeclarationExpr declaration = PsiTreeUtil.getParentOfType(declarationWrapper, PerlVariableDeclarationExpr.class);
                if (declaration != null) {
                    if (declaration.getParent() instanceof PsiPerlAssignExpr) {
                        PsiPerlAssignExpr assignmentExpression = (PsiPerlAssignExpr) declaration.getParent();
                        List<PsiPerlExpr> assignmentElements = assignmentExpression.getExprList();
                        if (!assignmentElements.isEmpty()) {
                            PsiPerlExpr lastExpression = assignmentElements.get(assignmentElements.size() - 1);
                            if (lastExpression != declaration) {
                                // source element is on the left side
                                if (lastExpression instanceof PerlMethodContainer) {
                                    return PerlSubUtil.getMethodReturnValue((PerlMethodContainer) lastExpression);
                                }
                                if (lastExpression instanceof PerlDerefExpression) {
                                    return ((PerlDerefExpression) lastExpression).guessType();
                                }
                            }
                        }
                    }
                }
                // fixme this is bad, because my $var1 && print $var1 will be valid, but it's not
                PerlLexicalScope perlLexicalScope = PsiTreeUtil.getParentOfType(declarationWrapper, PerlLexicalScope.class);
                assert perlLexicalScope != null : "Unable to find lexical scope for:" + declarationWrapper.getClass() + " at " + declarationWrapper.getTextOffset() + " in " + declarationWrapper.getContainingFile();
                final String[] guessResult = new String[] { null };
                int startOffset = declarationWrapper.getTextRange().getEndOffset();
                int endOffset = getTextRange().getStartOffset();
                if (startOffset < endOffset) {
                    PerlPsiUtil.processElementsInRange(perlLexicalScope, new TextRange(startOffset, endOffset), element -> {
                        if (element != PerlVariableMixin.this && element instanceof PsiPerlScalarVariable && element.getParent() instanceof PsiPerlAssignExpr) {
                            PsiElement variableNameElement1 = ((PsiPerlScalarVariable) element).getVariableNameElement();
                            if (variableNameElement1 != null && variableNameElement1.getReference() != null && variableNameElement1.getReference().isReferenceTo(declarationWrapper)) {
                                // found variable assignment
                                PsiPerlAssignExpr assignmentExpression = (PsiPerlAssignExpr) element.getParent();
                                List<PsiPerlExpr> assignmentElements = assignmentExpression.getExprList();
                                if (!assignmentElements.isEmpty()) {
                                    PsiPerlExpr lastExpression = assignmentElements.get(assignmentElements.size() - 1);
                                    if (lastExpression != element && lastExpression.getTextOffset() < getTextOffset()) {
                                        // source element is on the left side
                                        // fixme implement variables assignment support. Need to build kinda visitor with recursion control
                                        String returnValue = null;
                                        if (lastExpression instanceof PerlMethodContainer) {
                                            returnValue = PerlSubUtil.getMethodReturnValue((PerlMethodContainer) lastExpression);
                                        }
                                        if (lastExpression instanceof PerlDerefExpression) {
                                            returnValue = ((PerlDerefExpression) lastExpression).guessType();
                                        }
                                        if (StringUtil.isNotEmpty(returnValue)) {
                                            guessResult[0] = returnValue;
                                            return false;
                                        }
                                    }
                                }
                            }
                        }
                        return true;
                    });
                }
                if (guessResult[0] != null) {
                    return guessResult[0];
                }
            }
            // checking global declarations with explicit types
            for (PerlVariableDeclarationElement declaration : getGlobalDeclarations()) {
                if (declaration.getDeclaredType() != null) {
                    return declaration.getDeclaredType();
                }
            }
        }
    }
    return null;
}
Also used : TextRange(com.intellij.openapi.util.TextRange) PerlLexicalScope(com.perl5.lang.perl.psi.properties.PerlLexicalScope) PerlImplicitVariableDeclaration(com.perl5.lang.perl.psi.impl.PerlImplicitVariableDeclaration) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with PerlImplicitVariableDeclaration

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

the class PerlVariableReference method resolveInner.

@NotNull
@Override
protected ResolveResult[] resolveInner(boolean incompleteCode) {
    PsiElement elementParent = myElement.getParent();
    assert elementParent instanceof PerlVariable;
    PerlVariable perlVariable = (PerlVariable) elementParent;
    List<ResolveResult> result = new ArrayList<>();
    PerlVariableDeclarationElement lexicalDeclaration = PerlResolveUtil.getLexicalDeclaration(perlVariable);
    if (lexicalDeclaration == null || lexicalDeclaration.isGlobalDeclaration() && !(lexicalDeclaration instanceof PerlImplicitVariableDeclaration)) {
        // not found explicit lexically visible declarations
        // imports
        PerlVariableType actualType = perlVariable.getActualType();
        Project project = perlVariable.getProject();
        PerlNamespaceDefinitionElement namespaceContainer = PerlPackageUtil.getNamespaceContainerForElement(perlVariable);
        if (// not true if LPE in TemplateToolkit
        namespaceContainer != null) {
            String variableName = perlVariable.getName();
            if (actualType == PerlVariableType.SCALAR) {
                for (PerlExportDescriptor importEntry : namespaceContainer.getImportedScalarDescriptors()) {
                    if (importEntry.getImportedName().equals(variableName)) {
                        for (PerlVariableDeclarationElement targetVariable : PerlScalarUtil.getGlobalScalarDefinitions(project, importEntry.getTargetCanonicalName())) {
                            result.add(new PsiElementResolveResult(targetVariable));
                        }
                    }
                }
            } else if (actualType == PerlVariableType.ARRAY) {
                for (PerlExportDescriptor importEntry : namespaceContainer.getImportedArrayDescriptors()) {
                    if (importEntry.getImportedName().equals(variableName)) {
                        for (PerlVariableDeclarationElement targetVariable : PerlArrayUtil.getGlobalArrayDefinitions(project, importEntry.getTargetCanonicalName())) {
                            result.add(new PsiElementResolveResult(targetVariable));
                        }
                    }
                }
            } else if (actualType == PerlVariableType.HASH) {
                for (PerlExportDescriptor importEntry : namespaceContainer.getImportedHashDescriptors()) {
                    if (importEntry.getImportedName().equals(variableName)) {
                        for (PerlVariableDeclarationElement targetVariable : PerlHashUtil.getGlobalHashDefinitions(project, importEntry.getTargetCanonicalName())) {
                            result.add(new PsiElementResolveResult(targetVariable));
                        }
                    }
                }
            }
        }
        // our variable declaration
        for (PerlGlobVariable glob : perlVariable.getRelatedGlobs()) {
            result.add(new PsiElementResolveResult(glob));
        }
        // globs
        for (PerlVariableDeclarationElement globalDeclaration : perlVariable.getGlobalDeclarations()) {
            result.add(new PsiElementResolveResult(globalDeclaration));
        }
    } else {
        result.add(new PsiElementResolveResult(lexicalDeclaration));
    }
    return result.toArray(new ResolveResult[result.size()]);
}
Also used : PerlVariableDeclarationElement(com.perl5.lang.perl.psi.PerlVariableDeclarationElement) PerlVariableType(com.perl5.lang.perl.psi.utils.PerlVariableType) ArrayList(java.util.ArrayList) PsiElementResolveResult(com.intellij.psi.PsiElementResolveResult) Project(com.intellij.openapi.project.Project) PerlExportDescriptor(com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor) PerlNamespaceDefinitionElement(com.perl5.lang.perl.psi.PerlNamespaceDefinitionElement) PerlGlobVariable(com.perl5.lang.perl.psi.PerlGlobVariable) PerlVariable(com.perl5.lang.perl.psi.PerlVariable) PsiElementResolveResult(com.intellij.psi.PsiElementResolveResult) ResolveResult(com.intellij.psi.ResolveResult) PerlImplicitVariableDeclaration(com.perl5.lang.perl.psi.impl.PerlImplicitVariableDeclaration) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

PerlImplicitVariableDeclaration (com.perl5.lang.perl.psi.impl.PerlImplicitVariableDeclaration)3 PsiElement (com.intellij.psi.PsiElement)2 PerlVariable (com.perl5.lang.perl.psi.PerlVariable)2 PerlVariableDeclarationElement (com.perl5.lang.perl.psi.PerlVariableDeclarationElement)2 Project (com.intellij.openapi.project.Project)1 TextRange (com.intellij.openapi.util.TextRange)1 PsiElementResolveResult (com.intellij.psi.PsiElementResolveResult)1 ResolveResult (com.intellij.psi.ResolveResult)1 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)1 PerlExportDescriptor (com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor)1 PerlGlobVariable (com.perl5.lang.perl.psi.PerlGlobVariable)1 PerlNamespaceDefinitionElement (com.perl5.lang.perl.psi.PerlNamespaceDefinitionElement)1 PsiPerlVariableDeclarationLocal (com.perl5.lang.perl.psi.PsiPerlVariableDeclarationLocal)1 PerlBuiltInVariable (com.perl5.lang.perl.psi.impl.PerlBuiltInVariable)1 PerlLexicalScope (com.perl5.lang.perl.psi.properties.PerlLexicalScope)1 PerlVariableType (com.perl5.lang.perl.psi.utils.PerlVariableType)1 ArrayList (java.util.ArrayList)1 NotNull (org.jetbrains.annotations.NotNull)1 Nullable (org.jetbrains.annotations.Nullable)1