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);
}
}
});
}
}
}
}
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);
}
}
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);
}
}
}
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);
}
}
}
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;
}
Aggregations