Search in sources :

Example 1 with PsiPerlExpr

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

the class PerlFormattingStatementModifierUnwrap method apply.

@Override
public int apply() {
    int delta = 0;
    if (getMyModifier().isValid()) {
        PsiPerlExpr expression = PsiTreeUtil.getChildOfType(getMyModifier(), PsiPerlExpr.class);
        if (expression != null && expression instanceof PsiPerlParenthesisedExpr) {
            PsiPerlExpr nestedExpression = ((PsiPerlParenthesisedExpr) expression).getExpr();
            if (nestedExpression != null) {
                delta = nestedExpression.getNode().getTextLength() - expression.getNode().getTextLength();
                expression.replace(nestedExpression.copy());
            }
        }
    }
    return delta;
}
Also used : PsiPerlParenthesisedExpr(com.perl5.lang.perl.psi.PsiPerlParenthesisedExpr) PsiPerlExpr(com.perl5.lang.perl.psi.PsiPerlExpr)

Example 2 with PsiPerlExpr

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

the class PerlFormattingStatementModifierWrap method apply.

@Override
public int apply() {
    int delta = 0;
    if (getMyModifier().isValid()) {
        PsiPerlExpr expression = PsiTreeUtil.getChildOfType(getMyModifier(), PsiPerlExpr.class);
        if (expression != null && !(expression instanceof PsiPerlParenthesisedExpr)) {
            PsiPerlParenthesisedExpr parenthesisedExpression = PerlElementFactory.createParenthesisedExpression(getMyModifier().getProject());
            parenthesisedExpression.addAfter(expression.copy(), parenthesisedExpression.getFirstChild());
            delta = expression.getNode().getTextLength() - parenthesisedExpression.getNode().getTextLength();
            expression.replace(parenthesisedExpression);
        }
    }
    return delta;
}
Also used : PsiPerlParenthesisedExpr(com.perl5.lang.perl.psi.PsiPerlParenthesisedExpr) PsiPerlExpr(com.perl5.lang.perl.psi.PsiPerlExpr)

Example 3 with PsiPerlExpr

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

the class CompoundToStatementIntention method replaceWithStatement.

/**
 * Generating new code, extracting declarations from control expression and replacing compound statement if possible.
 *
 * @param compound      compound statement
 * @param statementText statement text
 * @param controlExpr   control expression (condition or iterable)
 */
private static void replaceWithStatement(@NotNull PerlConvertableCompound compound, @NotNull String statementText, @NotNull PsiPerlExpr controlExpr) {
    List<PsiElement> declarations = new ArrayList<>();
    controlExpr.accept(new PerlRecursiveVisitor() {

        @Override
        public void visitPerlVariableDeclarationExpr(@NotNull PerlVariableDeclarationExpr o) {
            declarations.add(o);
            super.visitPerlVariableDeclarationExpr(o);
        }
    });
    String controlExprText = controlExpr.getText();
    StringBuilder sb = new StringBuilder();
    if (!declarations.isEmpty()) {
        // extracting declarations from control statement
        TextRange controlExprTextRange = controlExpr.getTextRange();
        for (int i = declarations.size() - 1; i >= 0; i--) {
            PsiElement declaration = declarations.get(i);
            sb.append(declaration.getText()).append(";\n");
            PsiElement keywordElement = declaration.getFirstChild();
            if (keywordElement instanceof LeafPsiElement) {
                // removing keyword from control expression my $var => $var, my ($var1, $var2) => ($var1, $var2)
                controlExprText = keywordElement.getTextRange().shiftRight(-controlExprTextRange.getStartOffset()).replace(controlExprText, "");
            }
        }
    }
    sb.append(statementText).append(" ").append(compound.getFirstChild().getText()).append(" ").append(controlExprText).append(";");
    PerlFileImpl perlFile = PerlElementFactory.createFile(compound.getProject(), sb.toString());
    PsiPerlStatementImpl[] statements = PsiTreeUtil.getChildrenOfType(perlFile, PsiPerlStatementImpl.class);
    if (statements == null || statements.length == 0) {
        return;
    }
    PsiElement container = compound.getParent();
    if (container == null) {
        return;
    }
    container.addRangeBefore(statements[0], statements[statements.length - 1], compound);
    compound.delete();
}
Also used : PerlFileImpl(com.perl5.lang.perl.psi.impl.PerlFileImpl) ArrayList(java.util.ArrayList) PsiPerlStatementImpl(com.perl5.lang.perl.psi.impl.PsiPerlStatementImpl) TextRange(com.intellij.openapi.util.TextRange) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) PsiElement(com.intellij.psi.PsiElement)

Example 4 with PsiPerlExpr

use of com.perl5.lang.perl.psi.PsiPerlExpr 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 5 with PsiPerlExpr

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

the class StatementToCompoundIntention method invoke.

@Override
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
    PsiPerlStatementImpl statement = getStatement(element);
    if (statement == null) {
        return;
    }
    PsiPerlStatementModifier modifier = statement.getModifier();
    if (modifier == null) {
        return;
    }
    PsiElement keyword = modifier.getFirstChild();
    if (keyword == null) {
        return;
    }
    PsiPerlExpr modifierExpression = PsiTreeUtil.getChildOfType(modifier, PsiPerlExpr.class);
    PsiPerlExpr valueExpression = modifierExpression instanceof PsiPerlParenthesisedExpr ? ((PsiPerlParenthesisedExpr) modifierExpression).getExpr() : modifierExpression;
    String conditionText = valueExpression == null ? "" : valueExpression.getText();
    TextRange modifierRangeInStatement = TextRange.from(modifier.getStartOffsetInParent(), modifier.getTextLength());
    String statementText = modifierRangeInStatement.replace(statement.getText(), "");
    StringBuilder newCode = new StringBuilder();
    newCode.append(keyword.getText()).append("(").append(conditionText).append("){\n").append(statementText).append("\n}");
    PerlFileImpl fakeFile = PerlElementFactory.createFile(project, newCode.toString());
    PsiElement[] children = fakeFile.getChildren();
    assert children.length == 1;
    statement.replace(children[0]);
}
Also used : PerlFileImpl(com.perl5.lang.perl.psi.impl.PerlFileImpl) PsiPerlStatementImpl(com.perl5.lang.perl.psi.impl.PsiPerlStatementImpl) PsiPerlStatementModifier(com.perl5.lang.perl.psi.PsiPerlStatementModifier) PsiPerlParenthesisedExpr(com.perl5.lang.perl.psi.PsiPerlParenthesisedExpr) TextRange(com.intellij.openapi.util.TextRange) PsiPerlExpr(com.perl5.lang.perl.psi.PsiPerlExpr) PsiElement(com.intellij.psi.PsiElement)

Aggregations

TextRange (com.intellij.openapi.util.TextRange)3 PsiPerlExpr (com.perl5.lang.perl.psi.PsiPerlExpr)3 PsiPerlParenthesisedExpr (com.perl5.lang.perl.psi.PsiPerlParenthesisedExpr)3 PsiElement (com.intellij.psi.PsiElement)2 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)2 PerlFileImpl (com.perl5.lang.perl.psi.impl.PerlFileImpl)2 PsiPerlStatementImpl (com.perl5.lang.perl.psi.impl.PsiPerlStatementImpl)2 PsiPerlStatementModifier (com.perl5.lang.perl.psi.PsiPerlStatementModifier)1 PerlImplicitVariableDeclaration (com.perl5.lang.perl.psi.impl.PerlImplicitVariableDeclaration)1 PerlLexicalScope (com.perl5.lang.perl.psi.properties.PerlLexicalScope)1 ArrayList (java.util.ArrayList)1 Nullable (org.jetbrains.annotations.Nullable)1