Search in sources :

Example 11 with ControlFlow

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

the class PyCodeFragmentUtil method createCodeFragment.

@NotNull
public static PyCodeFragment createCodeFragment(@NotNull final ScopeOwner owner, @NotNull final PsiElement startInScope, @NotNull final PsiElement endInScope) throws CannotCreateCodeFragmentException {
    final int start = startInScope.getTextOffset();
    final int end = endInScope.getTextOffset() + endInScope.getTextLength();
    final ControlFlow flow = ControlFlowCache.getControlFlow(owner);
    if (flow == null) {
        throw new CannotCreateCodeFragmentException(PyBundle.message("refactoring.extract.method.error.undetermined.execution.flow"));
    }
    final List<Instruction> graph = Arrays.asList(flow.getInstructions());
    final List<Instruction> subGraph = getFragmentSubGraph(graph, start, end);
    final AnalysisResult subGraphAnalysis = analyseSubGraph(subGraph, start, end);
    if ((subGraphAnalysis.regularExits > 0 && subGraphAnalysis.returns > 0) || subGraphAnalysis.targetInstructions > 1 || subGraphAnalysis.outerLoopBreaks > 0) {
        throw new CannotCreateCodeFragmentException(PyBundle.message("refactoring.extract.method.error.interrupted.execution.flow"));
    }
    if (subGraphAnalysis.starImports > 0) {
        throw new CannotCreateCodeFragmentException(PyBundle.message("refactoring.extract.method.error.star.import"));
    }
    final Set<String> globalWrites = getGlobalWrites(subGraph, owner);
    final Set<String> nonlocalWrites = getNonlocalWrites(subGraph, owner);
    final Set<String> inputNames = new HashSet<>();
    for (PsiElement element : filterElementsInScope(getInputElements(subGraph, graph), owner)) {
        final String name = getName(element);
        if (name != null) {
            // Ignore "self" and "cls", they are generated automatically when extracting any method fragment
            if (resolvesToBoundMethodParameter(element)) {
                continue;
            }
            if (globalWrites.contains(name) || nonlocalWrites.contains(name)) {
                continue;
            }
            inputNames.add(name);
        }
    }
    final Set<String> outputNames = new HashSet<>();
    for (PsiElement element : getOutputElements(subGraph, graph)) {
        final String name = getName(element);
        if (name != null) {
            if (globalWrites.contains(name) || nonlocalWrites.contains(name)) {
                continue;
            }
            outputNames.add(name);
        }
    }
    final boolean yieldsFound = subGraphAnalysis.yieldExpressions > 0;
    if (yieldsFound && LanguageLevel.forElement(owner).isOlderThan(LanguageLevel.PYTHON33)) {
        throw new CannotCreateCodeFragmentException(PyBundle.message("refactoring.extract.method.error.yield"));
    }
    final boolean isAsync = owner instanceof PyFunction && ((PyFunction) owner).isAsync();
    return new PyCodeFragment(inputNames, outputNames, globalWrites, nonlocalWrites, subGraphAnalysis.returns > 0, yieldsFound, isAsync);
}
Also used : CannotCreateCodeFragmentException(com.intellij.codeInsight.codeFragment.CannotCreateCodeFragmentException) ReadWriteInstruction(com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction) Instruction(com.intellij.codeInsight.controlflow.Instruction) ControlFlow(com.intellij.codeInsight.controlflow.ControlFlow) NotNull(org.jetbrains.annotations.NotNull)

Example 12 with ControlFlow

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

the class ScopeUtil method getReadWriteElements.

@NotNull
public static Collection<PsiElement> getReadWriteElements(@NotNull String name, @NotNull ScopeOwner scopeOwner, boolean isReadAccess, boolean isWriteAccess) {
    ControlFlow flow = ControlFlowCache.getControlFlow(scopeOwner);
    Collection<PsiElement> result = new ArrayList<>();
    for (Instruction instr : flow.getInstructions()) {
        if (instr instanceof ReadWriteInstruction) {
            ReadWriteInstruction rw = (ReadWriteInstruction) instr;
            if (name.equals(rw.getName())) {
                ReadWriteInstruction.ACCESS access = rw.getAccess();
                if ((isReadAccess && access.isReadAccess()) || (isWriteAccess && access.isWriteAccess())) {
                    result.add(rw.getElement());
                }
            }
        }
    }
    return result;
}
Also used : ReadWriteInstruction(com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction) ArrayList(java.util.ArrayList) ReadWriteInstruction(com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction) Instruction(com.intellij.codeInsight.controlflow.Instruction) ControlFlow(com.intellij.codeInsight.controlflow.ControlFlow) StubBasedPsiElement(com.intellij.psi.StubBasedPsiElement) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 13 with ControlFlow

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

the class PyControlFlowBuilderTest method testTryBreak.

public void testTryBreak() {
    final String testName = getTestName(false).toLowerCase();
    configureByFile(testName + ".py");
    final ControlFlow flow = ControlFlowCache.getControlFlow((PyFunction) ((PyFile) myFile).getStatements().get(0));
    final String fullPath = getTestDataPath() + testName + ".txt";
    check(fullPath, flow);
}
Also used : ControlFlow(com.intellij.codeInsight.controlflow.ControlFlow)

Example 14 with ControlFlow

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

the class PyControlFlowBuilderTest method testQualifiedSelfReference.

public void testQualifiedSelfReference() {
    final String testName = getTestName(false).toLowerCase();
    configureByFile(testName + ".py");
    final String fullPath = getTestDataPath() + testName + ".txt";
    final PyClass pyClass = ((PyFile) myFile).getTopLevelClasses().get(0);
    final ControlFlow flow = ControlFlowCache.getControlFlow(pyClass.getMethods()[0]);
    check(fullPath, flow);
}
Also used : PyClass(com.jetbrains.python.psi.PyClass) ControlFlow(com.intellij.codeInsight.controlflow.ControlFlow)

Aggregations

ControlFlow (com.intellij.codeInsight.controlflow.ControlFlow)14 Instruction (com.intellij.codeInsight.controlflow.Instruction)7 ReadWriteInstruction (com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction)5 NotNull (org.jetbrains.annotations.NotNull)5 PsiElement (com.intellij.psi.PsiElement)4 PyClass (com.jetbrains.python.psi.PyClass)2 CannotCreateCodeFragmentException (com.intellij.codeInsight.codeFragment.CannotCreateCodeFragmentException)1 StubBasedPsiElement (com.intellij.psi.StubBasedPsiElement)1 ScopeOwner (com.jetbrains.python.codeInsight.controlflow.ScopeOwner)1 ArrayList (java.util.ArrayList)1