Search in sources :

Example 1 with Instruction

use of com.intellij.codeInsight.controlflow.Instruction in project intellij-community by JetBrains.

the class PyUnusedLocalInspectionVisitor method visitPyStringLiteralExpression.

@Override
public void visitPyStringLiteralExpression(PyStringLiteralExpression pyString) {
    final ScopeOwner owner = ScopeUtil.getScopeOwner(pyString);
    if (owner != null && !(owner instanceof PsiFile)) {
        final PyStatement instrAnchor = PsiTreeUtil.getParentOfType(pyString, PyStatement.class);
        if (instrAnchor == null)
            return;
        final Instruction[] instructions = ControlFlowCache.getControlFlow(owner).getInstructions();
        final int startInstruction = ControlFlowUtil.findInstructionNumberByElement(instructions, instrAnchor);
        if (startInstruction < 0)
            return;
        final Project project = pyString.getProject();
        final List<Pair<PsiElement, TextRange>> pairs = InjectedLanguageManager.getInstance(project).getInjectedPsiFiles(pyString);
        if (pairs != null) {
            for (Pair<PsiElement, TextRange> pair : pairs) {
                pair.getFirst().accept(new PyRecursiveElementVisitor() {

                    @Override
                    public void visitPyReferenceExpression(PyReferenceExpression expr) {
                        final PyExpression qualifier = expr.getQualifier();
                        if (qualifier != null) {
                            qualifier.accept(this);
                            return;
                        }
                        final String name = expr.getName();
                        if (name != null) {
                            analyzeReadsInScope(name, owner, instructions, startInstruction, pyString);
                        }
                    }
                });
            }
        }
    }
}
Also used : TextRange(com.intellij.openapi.util.TextRange) ReadWriteInstruction(com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction) Instruction(com.intellij.codeInsight.controlflow.Instruction) Project(com.intellij.openapi.project.Project) ScopeOwner(com.jetbrains.python.codeInsight.controlflow.ScopeOwner) PsiFile(com.intellij.psi.PsiFile) PsiElement(com.intellij.psi.PsiElement) Pair(com.intellij.openapi.util.Pair)

Example 2 with Instruction

use of com.intellij.codeInsight.controlflow.Instruction in project intellij-community by JetBrains.

the class PyControlFlowBuilderTest method check.

private static void check(final String fullPath, final ControlFlow flow) {
    final StringBuffer buffer = new StringBuffer();
    final Instruction[] instructions = flow.getInstructions();
    for (Instruction instruction : instructions) {
        buffer.append(instruction).append("\n");
    }
    final VirtualFile vFile = PyTestCase.getVirtualFileByName(fullPath);
    try {
        final String fileText = StringUtil.convertLineSeparators(VfsUtil.loadText(vFile), "\n");
        Assert.assertEquals(fileText.trim(), buffer.toString().trim());
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) IOException(java.io.IOException) Instruction(com.intellij.codeInsight.controlflow.Instruction)

Example 3 with Instruction

use of com.intellij.codeInsight.controlflow.Instruction in project intellij-community by JetBrains.

the class PyControlFlowBuilder method visitPyIfStatement.

@Override
public void visitPyIfStatement(final PyIfStatement node) {
    myBuilder.startNode(node);
    final PyIfPart ifPart = node.getIfPart();
    PyExpression condition = ifPart.getCondition();
    PyTypeAssertionEvaluator assertionEvaluator = new PyTypeAssertionEvaluator();
    if (condition != null) {
        condition.accept(this);
        condition.accept(assertionEvaluator);
    }
    // Set the head as the last instruction of condition
    PyElement lastCondition = condition;
    Instruction lastBranchingPoint = getPrevInstruction(condition);
    myBuilder.prevInstruction = lastBranchingPoint;
    final PyStatementList thenStatements = ifPart.getStatementList();
    myBuilder.startConditionalNode(thenStatements, condition, true);
    InstructionBuilder.addAssertInstructions(myBuilder, assertionEvaluator);
    thenStatements.accept(this);
    myBuilder.processPending((pendingScope, instruction) -> {
        if (pendingScope != null && PsiTreeUtil.isAncestor(thenStatements, pendingScope, false)) {
            myBuilder.addPendingEdge(node, instruction);
        } else {
            myBuilder.addPendingEdge(pendingScope, instruction);
        }
    });
    myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
    for (final PyIfPart part : node.getElifParts()) {
        // Set the head as the false branch
        myBuilder.prevInstruction = lastBranchingPoint;
        myBuilder.startConditionalNode(part, lastCondition, false);
        condition = part.getCondition();
        assertionEvaluator = new PyTypeAssertionEvaluator();
        if (condition != null) {
            lastCondition = condition;
            lastBranchingPoint = getPrevInstruction(lastCondition);
            condition.accept(this);
            condition.accept(assertionEvaluator);
        }
        // Set the head as the last instruction of condition
        myBuilder.prevInstruction = getPrevInstruction(lastCondition);
        myBuilder.startConditionalNode(part, lastCondition, true);
        final PyStatementList statementList = part.getStatementList();
        InstructionBuilder.addAssertInstructions(myBuilder, assertionEvaluator);
        statementList.accept(this);
        myBuilder.processPending((pendingScope, instruction) -> {
            if (pendingScope != null && PsiTreeUtil.isAncestor(part, pendingScope, false)) {
                myBuilder.addPendingEdge(node, instruction);
            } else {
                myBuilder.addPendingEdge(pendingScope, instruction);
            }
        });
        myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
    }
    boolean noPendingInScopeEdges = false;
    if (!assertionEvaluator.getDefinitions().isEmpty()) {
        final Ref<Boolean> pendingInScopeEdges = Ref.create(false);
        myBuilder.processPending((pendingScope, instruction) -> {
            if (pendingScope != null && PsiTreeUtil.isAncestor(node, pendingScope, false)) {
                pendingInScopeEdges.set(true);
            }
            myBuilder.addPendingEdge(pendingScope, instruction);
        });
        noPendingInScopeEdges = !pendingInScopeEdges.get();
    }
    final PyTypeAssertionEvaluator negativeAssertionEvaluator = new PyTypeAssertionEvaluator(false);
    final PyExpression ifCondition = ifPart.getCondition();
    // TODO: Add support for 'elif'
    if (ifCondition != null) {
        ifCondition.accept(negativeAssertionEvaluator);
    }
    final PyElsePart elseBranch = node.getElsePart();
    if (elseBranch != null) {
        // Set the head as the false branch
        myBuilder.prevInstruction = lastBranchingPoint;
        myBuilder.startConditionalNode(elseBranch, lastCondition, false);
        InstructionBuilder.addAssertInstructions(myBuilder, negativeAssertionEvaluator);
        elseBranch.accept(this);
        myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
    } else {
        if (noPendingInScopeEdges) {
            myBuilder.prevInstruction = lastBranchingPoint;
            InstructionBuilder.addAssertInstructions(myBuilder, negativeAssertionEvaluator);
            myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
        } else {
            myBuilder.addPendingEdge(node, lastBranchingPoint);
        }
    }
}
Also used : Instruction(com.intellij.codeInsight.controlflow.Instruction)

Example 4 with Instruction

use of com.intellij.codeInsight.controlflow.Instruction in project intellij-community by JetBrains.

the class PyControlFlowBuilder method visitPyComprehensionElement.

@Override
public void visitPyComprehensionElement(final PyComprehensionElement node) {
    PyExpression prevCondition = null;
    myBuilder.startNode(node);
    List<Instruction> iterators = new ArrayList<>();
    for (PyComprehensionComponent component : node.getComponents()) {
        if (component instanceof PyComprehensionForComponent) {
            final PyComprehensionForComponent c = (PyComprehensionForComponent) component;
            final PyExpression iteratedList = c.getIteratedList();
            final PyExpression iteratorVariable = c.getIteratorVariable();
            if (prevCondition != null) {
                myBuilder.startConditionalNode(iteratedList, prevCondition, true);
                prevCondition = null;
            } else {
                myBuilder.startNode(iteratedList);
            }
            iteratedList.accept(this);
            // for-loop continue and exit
            for (Instruction i : iterators) {
                myBuilder.addEdge(myBuilder.prevInstruction, i);
            }
            myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
            final Instruction iterator = myBuilder.startNode(iteratorVariable);
            iteratorVariable.accept(this);
            // Inner "for" and "if" constructs will be linked to all outer iterators
            iterators.add(iterator);
        } else if (component instanceof PyComprehensionIfComponent) {
            final PyComprehensionIfComponent c = (PyComprehensionIfComponent) component;
            final PyExpression condition = c.getTest();
            if (condition == null) {
                continue;
            }
            if (prevCondition != null) {
                myBuilder.startConditionalNode(condition, prevCondition, true);
            } else {
                myBuilder.startNode(condition);
            }
            condition.accept(this);
            // Condition is true for nested "for" and "if" constructs, next startNode() should create a conditional node
            prevCondition = condition;
            // for-loop continue and exit
            for (Instruction i : iterators) {
                myBuilder.addEdge(myBuilder.prevInstruction, i);
            }
            myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
        }
    }
    final PyExpression result = node.getResultExpression();
    if (result != null) {
        if (prevCondition != null) {
            myBuilder.startConditionalNode(result, prevCondition, true);
        } else {
            myBuilder.startNode(result);
        }
        result.accept(this);
        // for-loop continue
        for (Instruction i : iterators) {
            myBuilder.addEdge(myBuilder.prevInstruction, i);
        }
    }
}
Also used : ArrayList(java.util.ArrayList) Instruction(com.intellij.codeInsight.controlflow.Instruction)

Example 5 with Instruction

use of com.intellij.codeInsight.controlflow.Instruction in project intellij-community by JetBrains.

the class InstructionBuilder method buildInstructions.

public static List<Instruction> buildInstructions(ControlFlowBuilder builder, List<PyTypeAssertionEvaluator.Assertion> assertions) {
    List<Instruction> result = Lists.newArrayList();
    for (PyTypeAssertionEvaluator.Assertion def : assertions) {
        final PyReferenceExpression e = def.getElement();
        final QualifiedName qname = e.asQualifiedName();
        final String name = qname != null ? qname.toString() : e.getName();
        result.add(ReadWriteInstruction.assertType(builder, e, name, def.getTypeEvalFunction()));
    }
    return result;
}
Also used : QualifiedName(com.intellij.psi.util.QualifiedName) Instruction(com.intellij.codeInsight.controlflow.Instruction) PyReferenceExpression(com.jetbrains.python.psi.PyReferenceExpression)

Aggregations

Instruction (com.intellij.codeInsight.controlflow.Instruction)33 ReadWriteInstruction (com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction)15 NotNull (org.jetbrains.annotations.NotNull)12 PsiElement (com.intellij.psi.PsiElement)10 ControlFlow (com.intellij.codeInsight.controlflow.ControlFlow)7 ArrayList (java.util.ArrayList)5 ScopeOwner (com.jetbrains.python.codeInsight.controlflow.ScopeOwner)4 Pair (com.intellij.openapi.util.Pair)3 Scope (com.jetbrains.python.codeInsight.dataflow.scope.Scope)3 Project (com.intellij.openapi.project.Project)2 TextRange (com.intellij.openapi.util.TextRange)2 PyDefUseUtil (com.jetbrains.python.refactoring.PyDefUseUtil)2 TargetElementUtil (com.intellij.codeInsight.TargetElementUtil)1 CannotCreateCodeFragmentException (com.intellij.codeInsight.codeFragment.CannotCreateCodeFragmentException)1 HighlightManager (com.intellij.codeInsight.highlighting.HighlightManager)1 Language (com.intellij.lang.Language)1 InlineActionHandler (com.intellij.lang.refactoring.InlineActionHandler)1 ApplicationManager (com.intellij.openapi.application.ApplicationManager)1 CommandProcessor (com.intellij.openapi.command.CommandProcessor)1 Logger (com.intellij.openapi.diagnostic.Logger)1