mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 02:59:33 +07:00
PY-81676 Don't report lines with assert_never as unreachable
(cherry picked from commit afdbf35915823de02a6b8551f57770113d0feb2f) IJ-CR-172556 GitOrigin-RevId: 0f8526e2877736ac606db9ed4657a530a66d6f23
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5a60b17b4d
commit
adcc559e5c
@@ -1,17 +1,19 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.python.ast;
|
||||
package com.jetbrains.python.ast
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public interface PyAstCapturePattern extends PyAstPattern {
|
||||
@Override
|
||||
default boolean isIrrefutable() {
|
||||
return true;
|
||||
interface PyAstCapturePattern : PyAstPattern {
|
||||
override fun isIrrefutable(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
@Override
|
||||
default void acceptPyVisitor(PyAstElementVisitor pyVisitor) {
|
||||
pyVisitor.visitPyCapturePattern(this);
|
||||
fun getTarget(): PyAstTargetExpression {
|
||||
return requireNotNull(findChildByClass(PyAstTargetExpression::class.java)) { "${this}: target cannot be null" }
|
||||
}
|
||||
|
||||
override fun acceptPyVisitor(pyVisitor: PyAstElementVisitor) {
|
||||
pyVisitor.visitPyCapturePattern(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.codeInsight.controlflow.TransparentInstruction;
|
||||
import com.intellij.codeInsight.controlflow.impl.ConditionalInstructionImpl;
|
||||
import com.intellij.codeInsight.controlflow.impl.TransparentInstructionImpl;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -32,6 +33,7 @@ import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.*;
|
||||
import com.jetbrains.python.psi.types.PyNeverType;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -44,6 +46,9 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
private final ControlFlowBuilder myBuilder = new ControlFlowBuilder();
|
||||
|
||||
private @Nullable TrueFalseNodes myTrueFalseNodes;
|
||||
|
||||
// see com.jetbrains.python.PyPatternTypeTest.testMatchClassPatternShadowingCapture
|
||||
private final @NotNull List<String> myPatternBindingNames = new ArrayList<>();
|
||||
|
||||
private record TrueFalseNodes(@NotNull Instruction trueNode, @NotNull Instruction falseNode) {}
|
||||
|
||||
@@ -334,12 +339,46 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
public void visitPyMatchStatement(@NotNull PyMatchStatement matchStatement) {
|
||||
myBuilder.startNode(matchStatement);
|
||||
PyExpression subject = matchStatement.getSubject();
|
||||
String subjectName = PyTypeAssertionEvaluator.getAssertionTargetName(subject);
|
||||
if (subject != null) {
|
||||
subject.accept(this);
|
||||
}
|
||||
for (PyCaseClause caseClause : matchStatement.getCaseClauses()) {
|
||||
visitPyCaseClause(caseClause);
|
||||
Instruction nextClause = myBuilder.prevInstruction;
|
||||
boolean unreachable = false;
|
||||
for (PyCaseClause clause : matchStatement.getCaseClauses()) {
|
||||
myBuilder.prevInstruction = nextClause;
|
||||
nextClause = addTransparentInstruction();
|
||||
|
||||
myPatternBindingNames.clear();
|
||||
|
||||
PyPattern pattern = clause.getPattern();
|
||||
if (pattern != null) {
|
||||
pattern.accept(this);
|
||||
if (!myPatternBindingNames.contains(subjectName)) {
|
||||
addTypeAssertionNodes(clause, true);
|
||||
}
|
||||
}
|
||||
|
||||
PyExpression guard = clause.getGuardCondition();
|
||||
if (guard != null) {
|
||||
TransparentInstruction trueNode = addTransparentInstruction();
|
||||
visitCondition(guard, trueNode, nextClause);
|
||||
myBuilder.prevInstruction = trueNode;
|
||||
addTypeAssertionNodes(guard, true);
|
||||
}
|
||||
|
||||
if (unreachable) {
|
||||
addAssertTypeNever();
|
||||
}
|
||||
if (pattern != null && pattern.isIrrefutable()) {
|
||||
unreachable = true;
|
||||
}
|
||||
myBuilder.startNode(clause.getStatementList());
|
||||
clause.getStatementList().accept(this);
|
||||
myBuilder.addPendingEdge(matchStatement, myBuilder.prevInstruction);
|
||||
myBuilder.updatePendingElementScope(clause.getStatementList(), matchStatement);
|
||||
}
|
||||
myBuilder.prevInstruction = nextClause;
|
||||
myBuilder.addNodeAndCheckPending(new TransparentInstructionImpl(myBuilder, matchStatement, ""));
|
||||
if (!myBuilder.prevInstruction.allPred().isEmpty()) {
|
||||
addTypeAssertionNodes(matchStatement, false);
|
||||
@@ -348,53 +387,20 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
myBuilder.prevInstruction = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyCaseClause(@NotNull PyCaseClause clause) {
|
||||
PyPattern pattern = clause.getPattern();
|
||||
if (pattern != null) {
|
||||
pattern.accept(this);
|
||||
}
|
||||
|
||||
TransparentInstruction trueNode = addTransparentInstruction();
|
||||
TransparentInstruction falseNode = addTransparentInstruction();
|
||||
PyExpression guard = clause.getGuardCondition();
|
||||
if (guard != null) {
|
||||
visitCondition(guard, trueNode, falseNode);
|
||||
addTypeAssertionNodes(guard, true);
|
||||
myBuilder.addPendingEdge(clause, falseNode);
|
||||
}
|
||||
else {
|
||||
myBuilder.addEdge(myBuilder.prevInstruction, trueNode);
|
||||
}
|
||||
myBuilder.prevInstruction = trueNode;
|
||||
|
||||
clause.getStatementList().accept(this);
|
||||
|
||||
if (clause.getParent() instanceof PyMatchStatement matchStatement) {
|
||||
myBuilder.addPendingEdge(matchStatement, myBuilder.prevInstruction);
|
||||
myBuilder.updatePendingElementScope(clause.getStatementList(), matchStatement);
|
||||
}
|
||||
myBuilder.prevInstruction = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWildcardPattern(@NotNull PyWildcardPattern node) {
|
||||
myBuilder.startNode(node);
|
||||
addTypeAssertionNodes(node, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyPattern(@NotNull PyPattern node) {
|
||||
boolean isRefutable = !node.isIrrefutable();
|
||||
if (isRefutable) {
|
||||
myBuilder.addNodeAndCheckPending(new RefutablePatternInstruction(myBuilder, node, false));
|
||||
myBuilder.addPendingEdge(node.getParent(), myBuilder.prevInstruction);
|
||||
}
|
||||
else {
|
||||
myBuilder.startNode(node);
|
||||
}
|
||||
myBuilder.addPendingEdge(node.getParent(), myBuilder.prevInstruction);
|
||||
|
||||
node.acceptChildren(this);
|
||||
myBuilder.updatePendingElementScope(node, node.getParent());
|
||||
|
||||
addTypeAssertionNodes(node, true);
|
||||
if (isRefutable) {
|
||||
myBuilder.addNode(new RefutablePatternInstruction(myBuilder, node, true));
|
||||
}
|
||||
@@ -429,7 +435,6 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
node.getClassNameReference().accept(this);
|
||||
myBuilder.addPendingEdge(node.getParent(), myBuilder.prevInstruction);
|
||||
|
||||
addTypeAssertionNodes(node, true);
|
||||
node.getArgumentList().acceptChildren(this);
|
||||
myBuilder.updatePendingElementScope(node, node.getParent());
|
||||
|
||||
@@ -443,7 +448,6 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
node.getValue().accept(this);
|
||||
myBuilder.addPendingEdge(node.getParent(), myBuilder.prevInstruction);
|
||||
|
||||
addTypeAssertionNodes(node, true);
|
||||
myBuilder.addNode(new RefutablePatternInstruction(myBuilder, node, true));
|
||||
}
|
||||
|
||||
@@ -453,9 +457,20 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
// So no need to create an additional fail edge
|
||||
myBuilder.startNode(node);
|
||||
node.acceptChildren(this);
|
||||
myPatternBindingNames.add(node.getTarget().getName());
|
||||
myBuilder.updatePendingElementScope(node, node.getParent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyCapturePattern(@NotNull PyCapturePattern node) {
|
||||
node.acceptChildren(this);
|
||||
// Although capture pattern is irrefutable, I add fail edge
|
||||
// here to add some connection to the next case clause.
|
||||
// Perhaps this can be reworked and simplified later.
|
||||
myBuilder.addPendingEdge(node.getParent(), myBuilder.prevInstruction);
|
||||
myPatternBindingNames.add(node.getTarget().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyGroupPattern(@NotNull PyGroupPattern node) {
|
||||
// GroupPattern can't fail by itself – it fails only if its child fails.
|
||||
@@ -478,13 +493,16 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
if (condition != null) {
|
||||
visitCondition(condition, thenNode, elseNode);
|
||||
}
|
||||
myBuilder.prevInstruction = thenNode;
|
||||
|
||||
Boolean conditionResult = PyEvaluator.evaluateAsBooleanNoResolve(condition);
|
||||
myBuilder.prevInstruction = unreachable || Boolean.FALSE.equals(conditionResult) ? null : thenNode;
|
||||
if (unreachable || Boolean.FALSE.equals(conditionResult)) {
|
||||
// Condition is always False, or some previous condition is always True.
|
||||
addAssertTypeNever();
|
||||
}
|
||||
if (Boolean.TRUE.equals(conditionResult)) {
|
||||
unreachable = true;
|
||||
}
|
||||
|
||||
visitPyStatementPart(ifPart);
|
||||
|
||||
exitInstructions.add(myBuilder.prevInstruction);
|
||||
@@ -494,7 +512,7 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
final PyElsePart elsePart = node.getElsePart();
|
||||
if (elsePart != null) {
|
||||
if (unreachable) {
|
||||
myBuilder.prevInstruction = null;
|
||||
addAssertTypeNever();
|
||||
}
|
||||
visitPyStatementPart(elsePart);
|
||||
}
|
||||
@@ -1124,6 +1142,13 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
return instruction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to mark a branch as unreachable.
|
||||
*/
|
||||
private void addAssertTypeNever() {
|
||||
myBuilder.addNode(ReadWriteInstruction.assertType(myBuilder, null, null, context -> Ref.create(PyNeverType.NEVER)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to collect all pending edges
|
||||
* that we used to build CFG for `node`,
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.codeInsight.controlflow.Instruction
|
||||
import com.intellij.openapi.util.Version
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.psi.util.findParentOfType
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil
|
||||
import com.jetbrains.python.psi.*
|
||||
import com.jetbrains.python.psi.impl.PyEvaluator
|
||||
@@ -88,7 +89,16 @@ class PyDataFlow(scopeOwner: ScopeOwner, controlFlow: ControlFlow, private val c
|
||||
* - calls to functions annotated with `NoReturn`
|
||||
*/
|
||||
fun PsiElement.isUnreachableForInspection(context: TypeEvalContext): Boolean {
|
||||
return isUnreachableByControlFlow(context) && !isFirstTerminatingStatement(context)
|
||||
return PyUtil.getParameterizedCachedValue(this, context) { isUnreachableForInspectionNoCache(it) }
|
||||
}
|
||||
|
||||
private fun PsiElement.isUnreachableForInspectionNoCache(context: TypeEvalContext): Boolean {
|
||||
if (parent is PyElement && parent.isUnreachableForInspection(context)) return true
|
||||
return isUnreachableByControlFlow(context) && when (this) {
|
||||
is PyStatementList -> !(statements.firstOrNull()?.isIgnoredUnreachableStatement(context) ?: true)
|
||||
is PyStatement -> !this.isIgnoredUnreachableStatement(context)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,12 +138,11 @@ fun PsiElement.findInstructionNumber(flow: Array<Instruction>): Int {
|
||||
return -1
|
||||
}
|
||||
|
||||
private fun PsiElement.isFirstTerminatingStatement(context: TypeEvalContext): Boolean {
|
||||
if (this.isTerminatingStatement(context)) {
|
||||
val prevSibling = prevSiblingOfType<PyElement>() ?: return true
|
||||
return !prevSibling.isTerminatingStatement(context) && !prevSibling.isUnreachableByControlFlow(context)
|
||||
}
|
||||
return false
|
||||
private fun PyStatement.isIgnoredUnreachableStatement(context: TypeEvalContext): Boolean {
|
||||
val parentBlock = this.parent as? PyStatementList ?: return false
|
||||
if (parentBlock.statements[0] != this) return false
|
||||
val parentCompoundStatement = parentBlock.findParentOfType<PyStatement>() ?: return false
|
||||
return !parentCompoundStatement.isUnreachableByControlFlow(context) && isTerminatingStatement(context)
|
||||
}
|
||||
|
||||
private fun PsiElement.isTerminatingStatement(context: TypeEvalContext): Boolean {
|
||||
|
||||
@@ -168,10 +168,11 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyPattern(@NotNull PyPattern node) {
|
||||
final PsiElement parent = PsiTreeUtil.skipParentsOfType(node, PyCaseClause.class, PyGroupPattern.class, PyAsPattern.class, PyOrPattern.class);
|
||||
if (parent instanceof PyMatchStatement matchStatement) {
|
||||
pushAssertion(matchStatement.getSubject(), myPositive, context -> context.getType(node));
|
||||
public void visitPyCaseClause(@NotNull PyCaseClause node) {
|
||||
var pattern = node.getPattern();
|
||||
if (pattern == null) return;
|
||||
if (node.getParent() instanceof PyMatchStatement matchStatement) {
|
||||
pushAssertion(matchStatement.getSubject(), myPositive, context -> context.getType(pattern));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,6 +190,10 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
|
||||
for (PyCaseClause cs : matchStatement.getCaseClauses()) {
|
||||
if (cs.getPattern() == null) continue;
|
||||
if (cs.getGuardCondition() != null) continue;
|
||||
if (cs.getPattern().isIrrefutable()) {
|
||||
subjectType = PyNeverType.NEVER;
|
||||
break;
|
||||
}
|
||||
subjectType = Ref.deref(createAssertionType(subjectType, context.getType(cs.getPattern()), false, context));
|
||||
}
|
||||
|
||||
@@ -358,6 +363,19 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
public static @Nullable String getAssertionTargetName(@Nullable PyExpression expression) {
|
||||
PyExpression target = PyPsiUtils.flattenParens(expression);
|
||||
if (target instanceof PyAssignmentExpression walrus) {
|
||||
return getAssertionTargetName(walrus.getTarget());
|
||||
}
|
||||
if (target instanceof PyReferenceExpression || target instanceof PyTargetExpression) {
|
||||
if (!((PyQualifiedExpression)target).isQualified()) {
|
||||
return target.getName();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isIfReferenceStatement(@NotNull PyExpression node) {
|
||||
return PsiTreeUtil.skipParentsOfType(node, PyParenthesizedExpression.class) instanceof PyIfPart;
|
||||
}
|
||||
@@ -392,4 +410,4 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
|
||||
return myFunction;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import com.intellij.codeInsight.dataflow.map.DfaMapInstance;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.codeInsight.controlflow.CallInstruction;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
import com.jetbrains.python.codeInsight.controlflow.PyDataFlowKt;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeVariable;
|
||||
@@ -37,11 +37,8 @@ public class PyReachingDefsDfaInstance implements DfaMapInstance<ScopeVariable>
|
||||
if (element == null || ((PyFile) element.getContainingFile()).getLanguageLevel().isPython2()){
|
||||
return processReducedMap(map, instruction, element);
|
||||
}
|
||||
var scope = ScopeUtil.getScopeOwner(element);
|
||||
if (scope != null) {
|
||||
if (ControlFlowCache.getDataFlow(scope, myContext).isUnreachable(instruction)) {
|
||||
return UNREACHABLE_MARKER;
|
||||
}
|
||||
if (PyDataFlowKt.isUnreachableForInspection(element, myContext)) {
|
||||
return UNREACHABLE_MARKER;
|
||||
}
|
||||
if (instruction instanceof CallInstruction callInstruction) {
|
||||
if (callInstruction.isNoReturnCall(myContext)) {
|
||||
|
||||
@@ -5,13 +5,13 @@ import com.intellij.codeInspection.LocalInspectionToolSession
|
||||
import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.util.findParentInFile
|
||||
import com.jetbrains.python.PyPsiBundle
|
||||
import com.jetbrains.python.codeInsight.controlflow.isUnreachableForInspection
|
||||
import com.jetbrains.python.psi.PyElement
|
||||
import com.jetbrains.python.psi.PyStatement
|
||||
import com.jetbrains.python.psi.PyStatementList
|
||||
|
||||
/**
|
||||
* Detects unreachable code using control flow graph
|
||||
* Detects unreachable code using the control flow graph
|
||||
*/
|
||||
class PyUnreachableCodeInspection : PyInspection() {
|
||||
override fun buildVisitor(
|
||||
@@ -20,12 +20,16 @@ class PyUnreachableCodeInspection : PyInspection() {
|
||||
session: LocalInspectionToolSession
|
||||
): PsiElementVisitor {
|
||||
return object : PyInspectionVisitor(holder, getContext(session)) {
|
||||
override fun visitPyElement(node: PyElement) {
|
||||
override fun visitPyStatementList(node: PyStatementList) {
|
||||
if (node.parent.isUnreachableForInspection(myTypeEvalContext)) return
|
||||
if (node.isUnreachableForInspection(myTypeEvalContext)) {
|
||||
registerProblem(node, PyPsiBundle.message("INSP.unreachable.code"), ProblemHighlightType.LIKE_UNUSED_SYMBOL)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitPyStatement(node: PyStatement) {
|
||||
if (node.parent.isUnreachableForInspection(myTypeEvalContext)) return
|
||||
if (node.isUnreachableForInspection(myTypeEvalContext)) {
|
||||
if (node.findParentInFile { it.isUnreachableForInspection(myTypeEvalContext) } != null) {
|
||||
// We only want to highlight top level unreachable code
|
||||
return
|
||||
}
|
||||
registerProblem(node, PyPsiBundle.message("INSP.unreachable.code"), ProblemHighlightType.LIKE_UNUSED_SYMBOL)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,28 +5,30 @@
|
||||
4(5) element: null. Condition: c:true
|
||||
5(6) ASSERTTYPE ACCESS: c
|
||||
6(7) element: PyStatementList
|
||||
7(15) element: PyPassStatement
|
||||
7(16) element: PyPassStatement
|
||||
8(9,10) READ ACCESS: False
|
||||
9(15) element: null. Condition: False:false
|
||||
9(16) element: null. Condition: False:false
|
||||
10(11) element: null. Condition: False:true
|
||||
11() ASSERTTYPE ACCESS: False
|
||||
12(13) element: PyStatementList
|
||||
13(14) element: PyAssignmentStatement
|
||||
14(15) WRITE ACCESS: a
|
||||
15(16) element: PyIfStatement
|
||||
16(17,18) READ ACCESS: d
|
||||
17(22) element: null. Condition: d:false
|
||||
18(19) element: null. Condition: d:true
|
||||
19(20) ASSERTTYPE ACCESS: d
|
||||
20(21) element: PyStatementList
|
||||
21(31) element: PyPassStatement
|
||||
22(23,24) READ ACCESS: False
|
||||
23(29) element: null. Condition: False:false
|
||||
24(25) element: null. Condition: False:true
|
||||
25() ASSERTTYPE ACCESS: False
|
||||
26(27) element: PyStatementList
|
||||
27(28) element: PyAssignmentStatement
|
||||
28(31) WRITE ACCESS: b
|
||||
29(30) element: PyStatementList
|
||||
30(31) element: PyPassStatement
|
||||
31() element: null
|
||||
11(12) ASSERTTYPE ACCESS: False
|
||||
12(13) ASSERTTYPE ACCESS: null
|
||||
13(14) element: PyStatementList
|
||||
14(15) element: PyAssignmentStatement
|
||||
15(16) WRITE ACCESS: a
|
||||
16(17) element: PyIfStatement
|
||||
17(18,19) READ ACCESS: d
|
||||
18(23) element: null. Condition: d:false
|
||||
19(20) element: null. Condition: d:true
|
||||
20(21) ASSERTTYPE ACCESS: d
|
||||
21(22) element: PyStatementList
|
||||
22(33) element: PyPassStatement
|
||||
23(24,25) READ ACCESS: False
|
||||
24(31) element: null. Condition: False:false
|
||||
25(26) element: null. Condition: False:true
|
||||
26(27) ASSERTTYPE ACCESS: False
|
||||
27(28) ASSERTTYPE ACCESS: null
|
||||
28(29) element: PyStatementList
|
||||
29(30) element: PyAssignmentStatement
|
||||
30(33) WRITE ACCESS: b
|
||||
31(32) element: PyStatementList
|
||||
32(33) element: PyPassStatement
|
||||
33() element: null
|
||||
@@ -18,14 +18,15 @@
|
||||
17(18) element: null. Condition: d:true
|
||||
18(19) ASSERTTYPE ACCESS: d
|
||||
19(20) element: PyStatementList
|
||||
20(30) element: PyPassStatement
|
||||
20(31) element: PyPassStatement
|
||||
21(22,23) READ ACCESS: True
|
||||
22() element: null. Condition: True:false
|
||||
22(27) element: null. Condition: True:false
|
||||
23(24) element: null. Condition: True:true
|
||||
24(25) ASSERTTYPE ACCESS: True
|
||||
25(26) element: PyStatementList
|
||||
26(30) element: PyPassStatement
|
||||
27(28) element: PyStatementList
|
||||
28(29) element: PyAssignmentStatement
|
||||
29(30) WRITE ACCESS: e
|
||||
30() element: null
|
||||
26(31) element: PyPassStatement
|
||||
27(28) ASSERTTYPE ACCESS: null
|
||||
28(29) element: PyStatementList
|
||||
29(30) element: PyAssignmentStatement
|
||||
30(31) WRITE ACCESS: e
|
||||
31() element: null
|
||||
@@ -1,36 +1,39 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyIfStatement
|
||||
2(3,4) READ ACCESS: False
|
||||
3(9) element: null. Condition: False:false
|
||||
3(10) element: null. Condition: False:false
|
||||
4(5) element: null. Condition: False:true
|
||||
5() ASSERTTYPE ACCESS: False
|
||||
6(7) element: PyStatementList
|
||||
7(8) element: PyAssignmentStatement
|
||||
8(9) WRITE ACCESS: a
|
||||
9(10) element: PyIfStatement
|
||||
10(11,12) READ ACCESS: False
|
||||
11(17) element: null. Condition: False:false
|
||||
12(13) element: null. Condition: False:true
|
||||
13() ASSERTTYPE ACCESS: False
|
||||
14(15) element: PyStatementList
|
||||
15(16) element: PyAssignmentStatement
|
||||
16(19) WRITE ACCESS: b
|
||||
17(18) element: PyStatementList
|
||||
18(19) element: PyPassStatement
|
||||
19(20) element: PyIfStatement
|
||||
20(21,22) READ ACCESS: False
|
||||
21(27) element: null. Condition: False:false
|
||||
22(23) element: null. Condition: False:true
|
||||
23() ASSERTTYPE ACCESS: False
|
||||
24(25) element: PyStatementList
|
||||
25(26) element: PyAssignmentStatement
|
||||
26(35) WRITE ACCESS: c
|
||||
27(28,29) READ ACCESS: d
|
||||
28(33) element: null. Condition: d:false
|
||||
29(30) element: null. Condition: d:true
|
||||
30(31) ASSERTTYPE ACCESS: d
|
||||
31(32) element: PyStatementList
|
||||
32(35) element: PyPassStatement
|
||||
33(34) element: PyStatementList
|
||||
34(35) element: PyPassStatement
|
||||
35() element: null
|
||||
5(6) ASSERTTYPE ACCESS: False
|
||||
6(7) ASSERTTYPE ACCESS: null
|
||||
7(8) element: PyStatementList
|
||||
8(9) element: PyAssignmentStatement
|
||||
9(10) WRITE ACCESS: a
|
||||
10(11) element: PyIfStatement
|
||||
11(12,13) READ ACCESS: False
|
||||
12(19) element: null. Condition: False:false
|
||||
13(14) element: null. Condition: False:true
|
||||
14(15) ASSERTTYPE ACCESS: False
|
||||
15(16) ASSERTTYPE ACCESS: null
|
||||
16(17) element: PyStatementList
|
||||
17(18) element: PyAssignmentStatement
|
||||
18(21) WRITE ACCESS: b
|
||||
19(20) element: PyStatementList
|
||||
20(21) element: PyPassStatement
|
||||
21(22) element: PyIfStatement
|
||||
22(23,24) READ ACCESS: False
|
||||
23(30) element: null. Condition: False:false
|
||||
24(25) element: null. Condition: False:true
|
||||
25(26) ASSERTTYPE ACCESS: False
|
||||
26(27) ASSERTTYPE ACCESS: null
|
||||
27(28) element: PyStatementList
|
||||
28(29) element: PyAssignmentStatement
|
||||
29(38) WRITE ACCESS: c
|
||||
30(31,32) READ ACCESS: d
|
||||
31(36) element: null. Condition: d:false
|
||||
32(33) element: null. Condition: d:true
|
||||
33(34) ASSERTTYPE ACCESS: d
|
||||
34(35) element: PyStatementList
|
||||
35(38) element: PyPassStatement
|
||||
36(37) element: PyStatementList
|
||||
37(38) element: PyPassStatement
|
||||
38() element: null
|
||||
@@ -1,21 +1,22 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyIfStatement
|
||||
2(3,4) READ ACCESS: True
|
||||
3() element: null. Condition: True:false
|
||||
3(13) element: null. Condition: True:false
|
||||
4(5) element: null. Condition: True:true
|
||||
5(6) ASSERTTYPE ACCESS: True
|
||||
6(7) element: PyStatementList
|
||||
7(8) element: PyForStatement
|
||||
8(9) READ ACCESS: range
|
||||
9(10,18) element: PyCallExpression: range
|
||||
9(10,19) element: PyCallExpression: range
|
||||
10(11) element: PyTargetExpression: _
|
||||
11(12) WRITE ACCESS: _
|
||||
12(10,18) element: PyPrintStatement
|
||||
13(14) element: PyStatementList
|
||||
14(15) element: PyRaiseStatement
|
||||
15(16) READ ACCESS: Exception
|
||||
16(17) element: PyCallExpression: Exception
|
||||
17(20) raise: PyRaiseStatement
|
||||
18(19) element: PyReturnStatement
|
||||
19(20) READ ACCESS: True
|
||||
20() element: null
|
||||
12(10,19) element: PyPrintStatement
|
||||
13(14) ASSERTTYPE ACCESS: null
|
||||
14(15) element: PyStatementList
|
||||
15(16) element: PyRaiseStatement
|
||||
16(17) READ ACCESS: Exception
|
||||
17(18) element: PyCallExpression: Exception
|
||||
18(21) raise: PyRaiseStatement
|
||||
19(20) element: PyReturnStatement
|
||||
20(21) READ ACCESS: True
|
||||
21() element: null
|
||||
@@ -8,29 +8,32 @@
|
||||
7(8) element: PyPassStatement
|
||||
8(9) element: PyIfStatement
|
||||
9(10,11) READ ACCESS: True
|
||||
10() element: null. Condition: True:false
|
||||
10(15) element: null. Condition: True:false
|
||||
11(12) element: null. Condition: True:true
|
||||
12(13) ASSERTTYPE ACCESS: True
|
||||
13(14) element: PyStatementList
|
||||
14(18) element: PyPassStatement
|
||||
15(16) element: PyStatementList
|
||||
16(17) element: PyAssignmentStatement
|
||||
17(18) WRITE ACCESS: b
|
||||
18(19) element: PyIfStatement
|
||||
19(20,21) READ ACCESS: True
|
||||
20(25) element: null. Condition: True:false
|
||||
21(22) element: null. Condition: True:true
|
||||
22(23) ASSERTTYPE ACCESS: True
|
||||
23(24) element: PyStatementList
|
||||
24(35) element: PyPassStatement
|
||||
25(26,27) READ ACCESS: c
|
||||
26() element: null. Condition: c:false
|
||||
27(28) element: null. Condition: c:true
|
||||
28() ASSERTTYPE ACCESS: c
|
||||
29(30) element: PyStatementList
|
||||
30(31) element: PyAssignmentStatement
|
||||
31(35) WRITE ACCESS: d
|
||||
32(33) element: PyStatementList
|
||||
33(34) element: PyAssignmentStatement
|
||||
34(35) WRITE ACCESS: e
|
||||
35() element: null
|
||||
14(19) element: PyPassStatement
|
||||
15(16) ASSERTTYPE ACCESS: null
|
||||
16(17) element: PyStatementList
|
||||
17(18) element: PyAssignmentStatement
|
||||
18(19) WRITE ACCESS: b
|
||||
19(20) element: PyIfStatement
|
||||
20(21,22) READ ACCESS: True
|
||||
21(26) element: null. Condition: True:false
|
||||
22(23) element: null. Condition: True:true
|
||||
23(24) ASSERTTYPE ACCESS: True
|
||||
24(25) element: PyStatementList
|
||||
25(38) element: PyPassStatement
|
||||
26(27,28) READ ACCESS: c
|
||||
27(34) element: null. Condition: c:false
|
||||
28(29) element: null. Condition: c:true
|
||||
29(30) ASSERTTYPE ACCESS: c
|
||||
30(31) ASSERTTYPE ACCESS: null
|
||||
31(32) element: PyStatementList
|
||||
32(33) element: PyAssignmentStatement
|
||||
33(38) WRITE ACCESS: d
|
||||
34(35) ASSERTTYPE ACCESS: null
|
||||
35(36) element: PyStatementList
|
||||
36(37) element: PyAssignmentStatement
|
||||
37(38) WRITE ACCESS: e
|
||||
38() element: null
|
||||
@@ -1,18 +1,19 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyWhileStatement
|
||||
2(3,4) READ ACCESS: x
|
||||
3(15) element: null. Condition: x:false
|
||||
3(16) element: null. Condition: x:false
|
||||
4(5) element: null. Condition: x:true
|
||||
5(6) element: PyStatementList
|
||||
6(7) element: PyMatchStatement
|
||||
7(8) READ ACCESS: x
|
||||
8(9,12) refutable pattern: 42
|
||||
9(10) ASSERTTYPE ACCESS: x
|
||||
10(11) matched pattern: 42
|
||||
11(15) element: PyBreakStatement
|
||||
12(13) ASSERTTYPE ACCESS: x
|
||||
13(14) element: PyExpressionStatement
|
||||
14(1) READ ACCESS: y
|
||||
15(16) element: PyExpressionStatement
|
||||
16(17) READ ACCESS: z
|
||||
17() element: null
|
||||
8(9,13) refutable pattern: 42
|
||||
9(10) matched pattern: 42
|
||||
10(11) ASSERTTYPE ACCESS: x
|
||||
11(12) element: PyStatementList
|
||||
12(16) element: PyBreakStatement
|
||||
13(14) ASSERTTYPE ACCESS: x
|
||||
14(15) element: PyExpressionStatement
|
||||
15(1) READ ACCESS: y
|
||||
16(17) element: PyExpressionStatement
|
||||
17(18) READ ACCESS: z
|
||||
18() element: null
|
||||
@@ -1,18 +1,19 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyWhileStatement
|
||||
2(3,4) READ ACCESS: x
|
||||
3(15) element: null. Condition: x:false
|
||||
3(16) element: null. Condition: x:false
|
||||
4(5) element: null. Condition: x:true
|
||||
5(6) element: PyStatementList
|
||||
6(7) element: PyMatchStatement
|
||||
7(8) READ ACCESS: x
|
||||
8(9,12) refutable pattern: 42
|
||||
9(10) ASSERTTYPE ACCESS: x
|
||||
10(11) matched pattern: 42
|
||||
11(1) element: PyContinueStatement
|
||||
12(13) ASSERTTYPE ACCESS: x
|
||||
13(14) element: PyExpressionStatement
|
||||
14(1) READ ACCESS: y
|
||||
15(16) element: PyExpressionStatement
|
||||
16(17) READ ACCESS: z
|
||||
17() element: null
|
||||
8(9,13) refutable pattern: 42
|
||||
9(10) matched pattern: 42
|
||||
10(11) ASSERTTYPE ACCESS: x
|
||||
11(12) element: PyStatementList
|
||||
12(1) element: PyContinueStatement
|
||||
13(14) ASSERTTYPE ACCESS: x
|
||||
14(15) element: PyExpressionStatement
|
||||
15(1) READ ACCESS: y
|
||||
16(17) element: PyExpressionStatement
|
||||
17(18) READ ACCESS: z
|
||||
18() element: null
|
||||
@@ -2,11 +2,12 @@
|
||||
1(2) WRITE ACCESS: x
|
||||
2(3) element: PyMatchStatement
|
||||
3(4) READ ACCESS: x
|
||||
4(5,8) refutable pattern: 42
|
||||
5(6) ASSERTTYPE ACCESS: x
|
||||
6(7) matched pattern: 42
|
||||
7(11) element: PyReturnStatement
|
||||
8(9) ASSERTTYPE ACCESS: x
|
||||
9(10) element: PyExpressionStatement
|
||||
10(11) READ ACCESS: y
|
||||
11() element: null
|
||||
4(5,9) refutable pattern: 42
|
||||
5(6) matched pattern: 42
|
||||
6(7) ASSERTTYPE ACCESS: x
|
||||
7(8) element: PyStatementList
|
||||
8(12) element: PyReturnStatement
|
||||
9(10) ASSERTTYPE ACCESS: x
|
||||
10(11) element: PyExpressionStatement
|
||||
11(12) READ ACCESS: y
|
||||
12() element: null
|
||||
@@ -1,20 +1,23 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,12) refutable pattern: 1
|
||||
2(3,14) refutable pattern: 1
|
||||
3(4) matched pattern: 1
|
||||
4(5) element: PyMatchStatement
|
||||
5(6,9) refutable pattern: 11
|
||||
6(7) matched pattern: 11
|
||||
7(8) element: PyExpressionStatement
|
||||
8(10) READ ACCESS: y11
|
||||
9(10) ASSERTTYPE ACCESS: null
|
||||
10(11) element: PyExpressionStatement
|
||||
11(17) READ ACCESS: y1
|
||||
12(13,16) refutable pattern: 2
|
||||
13(14) matched pattern: 2
|
||||
14(15) element: PyExpressionStatement
|
||||
15(17) READ ACCESS: y2
|
||||
16(17) ASSERTTYPE ACCESS: null
|
||||
4(5) element: PyStatementList
|
||||
5(6) element: PyMatchStatement
|
||||
6(7,11) refutable pattern: 11
|
||||
7(8) matched pattern: 11
|
||||
8(9) element: PyStatementList
|
||||
9(10) element: PyExpressionStatement
|
||||
10(12) READ ACCESS: y11
|
||||
11(12) ASSERTTYPE ACCESS: null
|
||||
12(13) element: PyExpressionStatement
|
||||
13(20) READ ACCESS: y1
|
||||
14(15,19) refutable pattern: 2
|
||||
15(16) matched pattern: 2
|
||||
16(17) element: PyStatementList
|
||||
17(18) element: PyExpressionStatement
|
||||
18(19) READ ACCESS: z
|
||||
19() element: null
|
||||
18(20) READ ACCESS: y2
|
||||
19(20) ASSERTTYPE ACCESS: null
|
||||
20(21) element: PyExpressionStatement
|
||||
21(22) READ ACCESS: z
|
||||
22() element: null
|
||||
@@ -1,18 +1,21 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,10) refutable pattern: 1
|
||||
2(3,12) refutable pattern: 1
|
||||
3(4) matched pattern: 1
|
||||
4(5) element: PyMatchStatement
|
||||
5(6,9) refutable pattern: 11
|
||||
6(7) matched pattern: 11
|
||||
7(8) element: PyExpressionStatement
|
||||
8(15) READ ACCESS: y11
|
||||
9(15) ASSERTTYPE ACCESS: null
|
||||
10(11,14) refutable pattern: 2
|
||||
11(12) matched pattern: 2
|
||||
12(13) element: PyExpressionStatement
|
||||
13(15) READ ACCESS: y2
|
||||
14(15) ASSERTTYPE ACCESS: null
|
||||
4(5) element: PyStatementList
|
||||
5(6) element: PyMatchStatement
|
||||
6(7,11) refutable pattern: 11
|
||||
7(8) matched pattern: 11
|
||||
8(9) element: PyStatementList
|
||||
9(10) element: PyExpressionStatement
|
||||
10(18) READ ACCESS: y11
|
||||
11(18) ASSERTTYPE ACCESS: null
|
||||
12(13,17) refutable pattern: 2
|
||||
13(14) matched pattern: 2
|
||||
14(15) element: PyStatementList
|
||||
15(16) element: PyExpressionStatement
|
||||
16(17) READ ACCESS: z
|
||||
17() element: null
|
||||
16(18) READ ACCESS: y2
|
||||
17(18) ASSERTTYPE ACCESS: null
|
||||
18(19) element: PyExpressionStatement
|
||||
19(20) READ ACCESS: z
|
||||
20() element: null
|
||||
@@ -7,13 +7,14 @@
|
||||
6(7) matched pattern: 42
|
||||
7(11) matched pattern: [42]
|
||||
8(9) refutable pattern: foo.bar
|
||||
9(10,15) READ ACCESS: foo
|
||||
9(10,16) READ ACCESS: foo
|
||||
10(11) matched pattern: foo.bar
|
||||
11(12) matched pattern: [42] | foo.bar
|
||||
12(13) WRITE ACCESS: x
|
||||
13(14) element: PyExpressionStatement
|
||||
14(16) READ ACCESS: y
|
||||
15(16) ASSERTTYPE ACCESS: null
|
||||
16(17) element: PyExpressionStatement
|
||||
17(18) READ ACCESS: z
|
||||
18() element: null
|
||||
13(14) element: PyStatementList
|
||||
14(15) element: PyExpressionStatement
|
||||
15(17) READ ACCESS: y
|
||||
16(17) ASSERTTYPE ACCESS: null
|
||||
17(18) element: PyExpressionStatement
|
||||
18(19) READ ACCESS: z
|
||||
19() element: null
|
||||
@@ -1,11 +1,12 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,7) refutable pattern: [x]
|
||||
3(4) WRITE ACCESS: x
|
||||
2(3,8) refutable pattern: [x]
|
||||
3(4,8) WRITE ACCESS: x
|
||||
4(5) matched pattern: [x]
|
||||
5(6) element: PyExpressionStatement
|
||||
6(8) READ ACCESS: y
|
||||
7(8) ASSERTTYPE ACCESS: null
|
||||
8(9) element: PyExpressionStatement
|
||||
9(10) READ ACCESS: z
|
||||
10() element: null
|
||||
5(6) element: PyStatementList
|
||||
6(7) element: PyExpressionStatement
|
||||
7(9) READ ACCESS: y
|
||||
8(9) ASSERTTYPE ACCESS: null
|
||||
9(10) element: PyExpressionStatement
|
||||
10(11) READ ACCESS: z
|
||||
11() element: null
|
||||
@@ -1,8 +1,10 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) WRITE ACCESS: x
|
||||
3(4) element: PyExpressionStatement
|
||||
4(5) READ ACCESS: y
|
||||
5(6) element: PyExpressionStatement
|
||||
6(7) READ ACCESS: z
|
||||
7() element: null
|
||||
2(3,6) WRITE ACCESS: x
|
||||
3(4) element: PyStatementList
|
||||
4(5) element: PyExpressionStatement
|
||||
5(7) READ ACCESS: y
|
||||
6(7) ASSERTTYPE ACCESS: null
|
||||
7(8) element: PyExpressionStatement
|
||||
8(9) READ ACCESS: z
|
||||
9() element: null
|
||||
@@ -1,18 +1,19 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) refutable pattern: Class(1, attr=foo.bar)
|
||||
3(4,14) READ ACCESS: Class
|
||||
4(5,14) refutable pattern: 1
|
||||
3(4,15) READ ACCESS: Class
|
||||
4(5,15) refutable pattern: 1
|
||||
5(6) matched pattern: 1
|
||||
6(7,14) refutable pattern: attr=foo.bar
|
||||
6(7,15) refutable pattern: attr=foo.bar
|
||||
7(8) refutable pattern: foo.bar
|
||||
8(9,14) READ ACCESS: foo
|
||||
8(9,15) READ ACCESS: foo
|
||||
9(10) matched pattern: foo.bar
|
||||
10(11) matched pattern: attr=foo.bar
|
||||
11(12) matched pattern: Class(1, attr=foo.bar)
|
||||
12(13) element: PyExpressionStatement
|
||||
13(15) READ ACCESS: x
|
||||
14(15) ASSERTTYPE ACCESS: null
|
||||
15(16) element: PyExpressionStatement
|
||||
16(17) READ ACCESS: y
|
||||
17() element: null
|
||||
12(13) element: PyStatementList
|
||||
13(14) element: PyExpressionStatement
|
||||
14(16) READ ACCESS: x
|
||||
15(16) ASSERTTYPE ACCESS: null
|
||||
16(17) element: PyExpressionStatement
|
||||
17(18) READ ACCESS: y
|
||||
18() element: null
|
||||
@@ -1,16 +1,17 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) WRITE ACCESS: x
|
||||
2(3,13) WRITE ACCESS: x
|
||||
3(4) element: PyBinaryExpression
|
||||
4(5,6) READ ACCESS: x
|
||||
5(12) element: null. Condition: x > 0:false
|
||||
5(13) element: null. Condition: x > 0:false
|
||||
6(7) element: null. Condition: x > 0:true
|
||||
7(8,9) READ ACCESS: x
|
||||
8(12) element: null. Condition: x < 10:false
|
||||
8(13) element: null. Condition: x < 10:false
|
||||
9(10) element: null. Condition: x < 10:true
|
||||
10(11) element: PyExpressionStatement
|
||||
11(13) READ ACCESS: y
|
||||
12(13) ASSERTTYPE ACCESS: null
|
||||
13(14) element: PyExpressionStatement
|
||||
14(15) READ ACCESS: z
|
||||
15() element: null
|
||||
10(11) element: PyStatementList
|
||||
11(12) element: PyExpressionStatement
|
||||
12(14) READ ACCESS: y
|
||||
13(14) ASSERTTYPE ACCESS: null
|
||||
14(15) element: PyExpressionStatement
|
||||
15(16) READ ACCESS: z
|
||||
16() element: null
|
||||
@@ -1,20 +1,21 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) WRITE ACCESS: x
|
||||
2(3,17) WRITE ACCESS: x
|
||||
3(4) element: PyBinaryExpression
|
||||
4(5,6) READ ACCESS: x
|
||||
5(16) element: null. Condition: x % 4 == 0:false
|
||||
5(17) element: null. Condition: x % 4 == 0:false
|
||||
6(7) element: null. Condition: x % 4 == 0:true
|
||||
7(8) element: PyBinaryExpression
|
||||
8(9,10) READ ACCESS: x
|
||||
9(11) element: null. Condition: x % 400 == 0:false
|
||||
10(14) element: null. Condition: x % 400 == 0:true
|
||||
11(12,13) READ ACCESS: x
|
||||
12(16) element: null. Condition: x % 100 != 0:false
|
||||
12(17) element: null. Condition: x % 100 != 0:false
|
||||
13(14) element: null. Condition: x % 100 != 0:true
|
||||
14(15) element: PyExpressionStatement
|
||||
15(17) READ ACCESS: y
|
||||
16(17) ASSERTTYPE ACCESS: null
|
||||
17(18) element: PyExpressionStatement
|
||||
18(19) READ ACCESS: z
|
||||
19() element: null
|
||||
14(15) element: PyStatementList
|
||||
15(16) element: PyExpressionStatement
|
||||
16(18) READ ACCESS: y
|
||||
17(18) ASSERTTYPE ACCESS: null
|
||||
18(19) element: PyExpressionStatement
|
||||
19(20) READ ACCESS: z
|
||||
20() element: null
|
||||
@@ -1,16 +1,17 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) WRITE ACCESS: x
|
||||
2(3,13) WRITE ACCESS: x
|
||||
3(4) element: PyBinaryExpression
|
||||
4(5,6) READ ACCESS: x
|
||||
5(7) element: null. Condition: x > 0:false
|
||||
6(10) element: null. Condition: x > 0:true
|
||||
7(8,9) READ ACCESS: x
|
||||
8(12) element: null. Condition: x < 0:false
|
||||
8(13) element: null. Condition: x < 0:false
|
||||
9(10) element: null. Condition: x < 0:true
|
||||
10(11) element: PyExpressionStatement
|
||||
11(13) READ ACCESS: y
|
||||
12(13) ASSERTTYPE ACCESS: null
|
||||
13(14) element: PyExpressionStatement
|
||||
14(15) READ ACCESS: z
|
||||
15() element: null
|
||||
10(11) element: PyStatementList
|
||||
11(12) element: PyExpressionStatement
|
||||
12(14) READ ACCESS: y
|
||||
13(14) ASSERTTYPE ACCESS: null
|
||||
14(15) element: PyExpressionStatement
|
||||
15(16) READ ACCESS: z
|
||||
16() element: null
|
||||
@@ -1,17 +1,19 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,13) refutable pattern: {"foo": 1, **x}
|
||||
3(4,13) refutable pattern: "foo": 1
|
||||
4(5,13) refutable pattern: "foo"
|
||||
2(3,15) refutable pattern: {"foo": 1, **x}
|
||||
3(4,15) refutable pattern: "foo": 1
|
||||
4(5,15) refutable pattern: "foo"
|
||||
5(6) matched pattern: "foo"
|
||||
6(7,13) refutable pattern: 1
|
||||
6(7,15) refutable pattern: 1
|
||||
7(8) matched pattern: 1
|
||||
8(9) matched pattern: "foo": 1
|
||||
9(10) WRITE ACCESS: x
|
||||
10(11) matched pattern: {"foo": 1, **x}
|
||||
11(12) element: PyExpressionStatement
|
||||
12(14) READ ACCESS: y
|
||||
13(14) ASSERTTYPE ACCESS: null
|
||||
14(15) element: PyExpressionStatement
|
||||
15(16) READ ACCESS: z
|
||||
16() element: null
|
||||
9(10,15) element: PyDoubleStarPattern
|
||||
10(11,15) WRITE ACCESS: x
|
||||
11(12) matched pattern: {"foo": 1, **x}
|
||||
12(13) element: PyStatementList
|
||||
13(14) element: PyExpressionStatement
|
||||
14(16) READ ACCESS: y
|
||||
15(16) ASSERTTYPE ACCESS: null
|
||||
16(17) element: PyExpressionStatement
|
||||
17(18) READ ACCESS: z
|
||||
18() element: null
|
||||
@@ -1,23 +1,24 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,19) refutable pattern: [x1, x2, x3]
|
||||
3(4) WRITE ACCESS: x1
|
||||
4(5) WRITE ACCESS: x2
|
||||
5(6) WRITE ACCESS: x3
|
||||
2(3,20) refutable pattern: [x1, x2, x3]
|
||||
3(4,20) WRITE ACCESS: x1
|
||||
4(5,20) WRITE ACCESS: x2
|
||||
5(6,20) WRITE ACCESS: x3
|
||||
6(7) matched pattern: [x1, x2, x3]
|
||||
7(8) element: PyBinaryExpression
|
||||
8(9,10) READ ACCESS: x1
|
||||
9(11) element: null. Condition: x1:false
|
||||
10(17) element: null. Condition: x1:true
|
||||
11(12,13,14) READ ACCESS: x2
|
||||
12(19) element: null. Condition: x2:false
|
||||
12(20) element: null. Condition: x2:false
|
||||
13(17) element: null. Condition: x2:true
|
||||
14(15,16) READ ACCESS: x3
|
||||
15(19) element: null. Condition: (x1 or x2) > x3:false
|
||||
15(20) element: null. Condition: (x1 or x2) > x3:false
|
||||
16(17) element: null. Condition: (x1 or x2) > x3:true
|
||||
17(18) element: PyExpressionStatement
|
||||
18(20) READ ACCESS: y
|
||||
19(20) ASSERTTYPE ACCESS: null
|
||||
20(21) element: PyExpressionStatement
|
||||
21(22) READ ACCESS: z
|
||||
22() element: null
|
||||
17(18) element: PyStatementList
|
||||
18(19) element: PyExpressionStatement
|
||||
19(21) READ ACCESS: y
|
||||
20(21) ASSERTTYPE ACCESS: null
|
||||
21(22) element: PyExpressionStatement
|
||||
22(23) READ ACCESS: z
|
||||
23() element: null
|
||||
@@ -1,14 +1,15 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) refutable pattern: x | [x]
|
||||
3(7) WRITE ACCESS: x
|
||||
4(5,10) refutable pattern: [x]
|
||||
5(6) WRITE ACCESS: x
|
||||
3(4,7) WRITE ACCESS: x
|
||||
4(5,11) refutable pattern: [x]
|
||||
5(6,11) WRITE ACCESS: x
|
||||
6(7) matched pattern: [x]
|
||||
7(8) matched pattern: x | [x]
|
||||
8(9) element: PyExpressionStatement
|
||||
9(11) READ ACCESS: y
|
||||
10(11) ASSERTTYPE ACCESS: null
|
||||
11(12) element: PyExpressionStatement
|
||||
12(13) READ ACCESS: z
|
||||
13() element: null
|
||||
8(9) element: PyStatementList
|
||||
9(10) element: PyExpressionStatement
|
||||
10(12) READ ACCESS: y
|
||||
11(12) ASSERTTYPE ACCESS: null
|
||||
12(13) element: PyExpressionStatement
|
||||
13(14) READ ACCESS: z
|
||||
14() element: null
|
||||
@@ -2,12 +2,14 @@
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) refutable pattern: [x] | x
|
||||
3(4,6) refutable pattern: [x]
|
||||
4(5) WRITE ACCESS: x
|
||||
4(5,6) WRITE ACCESS: x
|
||||
5(7) matched pattern: [x]
|
||||
6(7) WRITE ACCESS: x
|
||||
6(7,11) WRITE ACCESS: x
|
||||
7(8) matched pattern: [x] | x
|
||||
8(9) element: PyExpressionStatement
|
||||
9(10) READ ACCESS: y
|
||||
10(11) element: PyExpressionStatement
|
||||
11(12) READ ACCESS: z
|
||||
12() element: null
|
||||
8(9) element: PyStatementList
|
||||
9(10) element: PyExpressionStatement
|
||||
10(12) READ ACCESS: y
|
||||
11(12) ASSERTTYPE ACCESS: null
|
||||
12(13) element: PyExpressionStatement
|
||||
13(14) READ ACCESS: z
|
||||
14() element: null
|
||||
@@ -1,10 +1,11 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,6) refutable pattern: 42
|
||||
2(3,7) refutable pattern: 42
|
||||
3(4) matched pattern: 42
|
||||
4(5) element: PyExpressionStatement
|
||||
5(7) READ ACCESS: y
|
||||
6(7) ASSERTTYPE ACCESS: null
|
||||
7(8) element: PyExpressionStatement
|
||||
8(9) READ ACCESS: z
|
||||
9() element: null
|
||||
4(5) element: PyStatementList
|
||||
5(6) element: PyExpressionStatement
|
||||
6(8) READ ACCESS: y
|
||||
7(8) ASSERTTYPE ACCESS: null
|
||||
8(9) element: PyExpressionStatement
|
||||
9(10) READ ACCESS: z
|
||||
10() element: null
|
||||
@@ -1,23 +1,24 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,19) refutable pattern: {'foo': 1, 'bar': foo.bar}
|
||||
3(4,19) refutable pattern: 'foo': 1
|
||||
4(5,19) refutable pattern: 'foo'
|
||||
2(3,20) refutable pattern: {'foo': 1, 'bar': foo.bar}
|
||||
3(4,20) refutable pattern: 'foo': 1
|
||||
4(5,20) refutable pattern: 'foo'
|
||||
5(6) matched pattern: 'foo'
|
||||
6(7,19) refutable pattern: 1
|
||||
6(7,20) refutable pattern: 1
|
||||
7(8) matched pattern: 1
|
||||
8(9) matched pattern: 'foo': 1
|
||||
9(10,19) refutable pattern: 'bar': foo.bar
|
||||
10(11,19) refutable pattern: 'bar'
|
||||
9(10,20) refutable pattern: 'bar': foo.bar
|
||||
10(11,20) refutable pattern: 'bar'
|
||||
11(12) matched pattern: 'bar'
|
||||
12(13) refutable pattern: foo.bar
|
||||
13(14,19) READ ACCESS: foo
|
||||
13(14,20) READ ACCESS: foo
|
||||
14(15) matched pattern: foo.bar
|
||||
15(16) matched pattern: 'bar': foo.bar
|
||||
16(17) matched pattern: {'foo': 1, 'bar': foo.bar}
|
||||
17(18) element: PyExpressionStatement
|
||||
18(20) READ ACCESS: x
|
||||
19(20) ASSERTTYPE ACCESS: null
|
||||
20(21) element: PyExpressionStatement
|
||||
21(22) READ ACCESS: y
|
||||
22() element: null
|
||||
17(18) element: PyStatementList
|
||||
18(19) element: PyExpressionStatement
|
||||
19(21) READ ACCESS: x
|
||||
20(21) ASSERTTYPE ACCESS: null
|
||||
21(22) element: PyExpressionStatement
|
||||
22(23) READ ACCESS: y
|
||||
23() element: null
|
||||
@@ -1,13 +1,15 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,9) refutable pattern: [1, *x]
|
||||
3(4,9) refutable pattern: 1
|
||||
2(3,11) refutable pattern: [1, *x]
|
||||
3(4,11) refutable pattern: 1
|
||||
4(5) matched pattern: 1
|
||||
5(6) WRITE ACCESS: x
|
||||
6(7) matched pattern: [1, *x]
|
||||
7(8) element: PyExpressionStatement
|
||||
8(10) READ ACCESS: y
|
||||
9(10) ASSERTTYPE ACCESS: null
|
||||
10(11) element: PyExpressionStatement
|
||||
11(12) READ ACCESS: z
|
||||
12() element: null
|
||||
5(6,11) element: PySingleStarPattern
|
||||
6(7,11) WRITE ACCESS: x
|
||||
7(8) matched pattern: [1, *x]
|
||||
8(9) element: PyStatementList
|
||||
9(10) element: PyExpressionStatement
|
||||
10(12) READ ACCESS: y
|
||||
11(12) ASSERTTYPE ACCESS: null
|
||||
12(13) element: PyExpressionStatement
|
||||
13(14) READ ACCESS: z
|
||||
14() element: null
|
||||
@@ -6,13 +6,14 @@
|
||||
5(6) refutable pattern: 2 | 3
|
||||
6(7,8) refutable pattern: 2
|
||||
7(10) matched pattern: 2
|
||||
8(9,14) refutable pattern: 3
|
||||
8(9,15) refutable pattern: 3
|
||||
9(10) matched pattern: 3
|
||||
10(11) matched pattern: 2 | 3
|
||||
11(12) matched pattern: 1 | (2 | 3)
|
||||
12(13) element: PyExpressionStatement
|
||||
13(15) READ ACCESS: x
|
||||
14(15) ASSERTTYPE ACCESS: null
|
||||
15(16) element: PyExpressionStatement
|
||||
16(17) READ ACCESS: y
|
||||
17() element: null
|
||||
12(13) element: PyStatementList
|
||||
13(14) element: PyExpressionStatement
|
||||
14(16) READ ACCESS: x
|
||||
15(16) ASSERTTYPE ACCESS: null
|
||||
16(17) element: PyExpressionStatement
|
||||
17(18) READ ACCESS: y
|
||||
18() element: null
|
||||
@@ -1,8 +1,10 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) WRITE ACCESS: x
|
||||
3(4) element: PyExpressionStatement
|
||||
4(5) READ ACCESS: y
|
||||
5(6) element: PyExpressionStatement
|
||||
6(7) READ ACCESS: z
|
||||
7() element: null
|
||||
2(3,6) WRITE ACCESS: x
|
||||
3(4) element: PyStatementList
|
||||
4(5) element: PyExpressionStatement
|
||||
5(7) READ ACCESS: y
|
||||
6(7) ASSERTTYPE ACCESS: null
|
||||
7(8) element: PyExpressionStatement
|
||||
8(9) READ ACCESS: z
|
||||
9() element: null
|
||||
@@ -2,17 +2,18 @@
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) refutable pattern: [x] | (foo.bar as x)
|
||||
3(4,6) refutable pattern: [x]
|
||||
4(5) WRITE ACCESS: x
|
||||
4(5,6) WRITE ACCESS: x
|
||||
5(11) matched pattern: [x]
|
||||
6(7) element: PyAsPattern
|
||||
7(8) refutable pattern: foo.bar
|
||||
8(9,14) READ ACCESS: foo
|
||||
8(9,15) READ ACCESS: foo
|
||||
9(10) matched pattern: foo.bar
|
||||
10(11) WRITE ACCESS: x
|
||||
11(12) matched pattern: [x] | (foo.bar as x)
|
||||
12(13) element: PyExpressionStatement
|
||||
13(15) READ ACCESS: y
|
||||
14(15) ASSERTTYPE ACCESS: null
|
||||
15(16) element: PyExpressionStatement
|
||||
16(17) READ ACCESS: z
|
||||
17() element: null
|
||||
12(13) element: PyStatementList
|
||||
13(14) element: PyExpressionStatement
|
||||
14(16) READ ACCESS: y
|
||||
15(16) ASSERTTYPE ACCESS: null
|
||||
16(17) element: PyExpressionStatement
|
||||
17(18) READ ACCESS: z
|
||||
18() element: null
|
||||
@@ -3,12 +3,13 @@
|
||||
2(3) refutable pattern: [] | 42
|
||||
3(4,5) refutable pattern: []
|
||||
4(7) matched pattern: []
|
||||
5(6,10) refutable pattern: 42
|
||||
5(6,11) refutable pattern: 42
|
||||
6(7) matched pattern: 42
|
||||
7(8) matched pattern: [] | 42
|
||||
8(9) element: PyExpressionStatement
|
||||
9(11) READ ACCESS: y
|
||||
10(11) ASSERTTYPE ACCESS: null
|
||||
11(12) element: PyExpressionStatement
|
||||
12(13) READ ACCESS: z
|
||||
13() element: null
|
||||
8(9) element: PyStatementList
|
||||
9(10) element: PyExpressionStatement
|
||||
10(12) READ ACCESS: y
|
||||
11(12) ASSERTTYPE ACCESS: null
|
||||
12(13) element: PyExpressionStatement
|
||||
13(14) READ ACCESS: z
|
||||
14() element: null
|
||||
@@ -1,13 +1,14 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) refutable pattern: _ | 42
|
||||
3(6) element: PyWildcardPattern
|
||||
4(5,9) refutable pattern: 42
|
||||
3(4,6) element: PyWildcardPattern
|
||||
4(5,10) refutable pattern: 42
|
||||
5(6) matched pattern: 42
|
||||
6(7) matched pattern: _ | 42
|
||||
7(8) element: PyExpressionStatement
|
||||
8(10) READ ACCESS: y
|
||||
9(10) ASSERTTYPE ACCESS: null
|
||||
10(11) element: PyExpressionStatement
|
||||
11(12) READ ACCESS: z
|
||||
12() element: null
|
||||
7(8) element: PyStatementList
|
||||
8(9) element: PyExpressionStatement
|
||||
9(11) READ ACCESS: y
|
||||
10(11) ASSERTTYPE ACCESS: null
|
||||
11(12) element: PyExpressionStatement
|
||||
12(13) READ ACCESS: z
|
||||
13() element: null
|
||||
@@ -1,18 +1,19 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,14) refutable pattern: [x]
|
||||
3(4) WRITE ACCESS: x
|
||||
2(3,15) refutable pattern: [x]
|
||||
3(4,15) WRITE ACCESS: x
|
||||
4(5) matched pattern: [x]
|
||||
5(6) element: PyBinaryExpression
|
||||
6(7,8) READ ACCESS: x
|
||||
7(14) element: null. Condition: x > 0:false
|
||||
7(15) element: null. Condition: x > 0:false
|
||||
8(9) element: null. Condition: x > 0:true
|
||||
9(10,11) READ ACCESS: x
|
||||
10(14) element: null. Condition: x % 2 == 0:false
|
||||
10(15) element: null. Condition: x % 2 == 0:false
|
||||
11(12) element: null. Condition: x % 2 == 0:true
|
||||
12(13) element: PyExpressionStatement
|
||||
13(15) READ ACCESS: y
|
||||
14(15) ASSERTTYPE ACCESS: null
|
||||
15(16) element: PyExpressionStatement
|
||||
16(17) READ ACCESS: z
|
||||
17() element: null
|
||||
12(13) element: PyStatementList
|
||||
13(14) element: PyExpressionStatement
|
||||
14(16) READ ACCESS: y
|
||||
15(16) ASSERTTYPE ACCESS: null
|
||||
16(17) element: PyExpressionStatement
|
||||
17(18) READ ACCESS: z
|
||||
18() element: null
|
||||
@@ -1,15 +1,16 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,11) refutable pattern: [1, foo.bar]
|
||||
3(4,11) refutable pattern: 1
|
||||
2(3,12) refutable pattern: [1, foo.bar]
|
||||
3(4,12) refutable pattern: 1
|
||||
4(5) matched pattern: 1
|
||||
5(6) refutable pattern: foo.bar
|
||||
6(7,11) READ ACCESS: foo
|
||||
6(7,12) READ ACCESS: foo
|
||||
7(8) matched pattern: foo.bar
|
||||
8(9) matched pattern: [1, foo.bar]
|
||||
9(10) element: PyExpressionStatement
|
||||
10(12) READ ACCESS: x
|
||||
11(12) ASSERTTYPE ACCESS: null
|
||||
12(13) element: PyExpressionStatement
|
||||
13(14) READ ACCESS: y
|
||||
14() element: null
|
||||
9(10) element: PyStatementList
|
||||
10(11) element: PyExpressionStatement
|
||||
11(13) READ ACCESS: x
|
||||
12(13) ASSERTTYPE ACCESS: null
|
||||
13(14) element: PyExpressionStatement
|
||||
14(15) READ ACCESS: y
|
||||
15() element: null
|
||||
@@ -1,15 +1,16 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,11) refutable pattern: [1 | x]
|
||||
2(3,12) refutable pattern: [1 | x]
|
||||
3(4) refutable pattern: 1 | x
|
||||
4(5,6) refutable pattern: 1
|
||||
5(7) matched pattern: 1
|
||||
6(7) WRITE ACCESS: x
|
||||
6(7,12) WRITE ACCESS: x
|
||||
7(8) matched pattern: 1 | x
|
||||
8(9) matched pattern: [1 | x]
|
||||
9(10) element: PyExpressionStatement
|
||||
10(12) READ ACCESS: y
|
||||
11(12) ASSERTTYPE ACCESS: null
|
||||
12(13) element: PyExpressionStatement
|
||||
13(14) READ ACCESS: z
|
||||
14() element: null
|
||||
9(10) element: PyStatementList
|
||||
10(11) element: PyExpressionStatement
|
||||
11(13) READ ACCESS: y
|
||||
12(13) ASSERTTYPE ACCESS: null
|
||||
13(14) element: PyExpressionStatement
|
||||
14(15) READ ACCESS: z
|
||||
15() element: null
|
||||
@@ -1,12 +1,13 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) WRITE ACCESS: x
|
||||
2(3,9) WRITE ACCESS: x
|
||||
3(4,5) READ ACCESS: x
|
||||
4(8) element: null. Condition: x > 0:false
|
||||
4(9) element: null. Condition: x > 0:false
|
||||
5(6) element: null. Condition: x > 0:true
|
||||
6(7) element: PyExpressionStatement
|
||||
7(9) READ ACCESS: y
|
||||
8(9) ASSERTTYPE ACCESS: null
|
||||
9(10) element: PyExpressionStatement
|
||||
10(11) READ ACCESS: z
|
||||
11() element: null
|
||||
6(7) element: PyStatementList
|
||||
7(8) element: PyExpressionStatement
|
||||
8(10) READ ACCESS: y
|
||||
9(10) ASSERTTYPE ACCESS: null
|
||||
10(11) element: PyExpressionStatement
|
||||
11(12) READ ACCESS: z
|
||||
12() element: null
|
||||
@@ -1,8 +1,10 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) element: PyWildcardPattern
|
||||
3(4) element: PyExpressionStatement
|
||||
4(5) READ ACCESS: y
|
||||
5(6) element: PyExpressionStatement
|
||||
6(7) READ ACCESS: z
|
||||
7() element: null
|
||||
2(3,6) element: PyWildcardPattern
|
||||
3(4) element: PyStatementList
|
||||
4(5) element: PyExpressionStatement
|
||||
5(7) READ ACCESS: y
|
||||
6(7) ASSERTTYPE ACCESS: null
|
||||
7(8) element: PyExpressionStatement
|
||||
8(9) READ ACCESS: z
|
||||
9() element: null
|
||||
@@ -1,13 +1,15 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,9) refutable pattern: [1, *_]
|
||||
3(4,9) refutable pattern: 1
|
||||
2(3,11) refutable pattern: [1, *_]
|
||||
3(4,11) refutable pattern: 1
|
||||
4(5) matched pattern: 1
|
||||
5(6) element: PyWildcardPattern
|
||||
6(7) matched pattern: [1, *_]
|
||||
7(8) element: PyExpressionStatement
|
||||
8(10) READ ACCESS: y
|
||||
9(10) ASSERTTYPE ACCESS: null
|
||||
10(11) element: PyExpressionStatement
|
||||
11(12) READ ACCESS: z
|
||||
12() element: null
|
||||
5(6,11) element: PySingleStarPattern
|
||||
6(7,11) element: PyWildcardPattern
|
||||
7(8) matched pattern: [1, *_]
|
||||
8(9) element: PyStatementList
|
||||
9(10) element: PyExpressionStatement
|
||||
10(12) READ ACCESS: y
|
||||
11(12) ASSERTTYPE ACCESS: null
|
||||
12(13) element: PyExpressionStatement
|
||||
13(14) READ ACCESS: z
|
||||
14() element: null
|
||||
@@ -1,13 +1,16 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3) WRITE ACCESS: x
|
||||
3(4) element: PyExpressionStatement
|
||||
4(10) READ ACCESS: y
|
||||
5(6,9) refutable pattern: 42
|
||||
6(7) matched pattern: 42
|
||||
7(8) element: PyExpressionStatement
|
||||
8(10) READ ACCESS: y
|
||||
9(10) ASSERTTYPE ACCESS: null
|
||||
2(3,6) WRITE ACCESS: x
|
||||
3(4) element: PyStatementList
|
||||
4(5) element: PyExpressionStatement
|
||||
5(13) READ ACCESS: y
|
||||
6(7,12) refutable pattern: 42
|
||||
7(8) matched pattern: 42
|
||||
8(9) ASSERTTYPE ACCESS: null
|
||||
9(10) element: PyStatementList
|
||||
10(11) element: PyExpressionStatement
|
||||
11(12) READ ACCESS: z
|
||||
12() element: null
|
||||
11(13) READ ACCESS: y
|
||||
12(13) ASSERTTYPE ACCESS: null
|
||||
13(14) element: PyExpressionStatement
|
||||
14(15) READ ACCESS: z
|
||||
15() element: null
|
||||
@@ -1,12 +1,15 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyMatchStatement
|
||||
2(3,6) refutable pattern: 42
|
||||
2(3,7) refutable pattern: 42
|
||||
3(4) matched pattern: 42
|
||||
4(5) element: PyExpressionStatement
|
||||
5(9) READ ACCESS: y
|
||||
6(7) WRITE ACCESS: x
|
||||
7(8) element: PyExpressionStatement
|
||||
8(9) READ ACCESS: y
|
||||
4(5) element: PyStatementList
|
||||
5(6) element: PyExpressionStatement
|
||||
6(12) READ ACCESS: y
|
||||
7(8,11) WRITE ACCESS: x
|
||||
8(9) element: PyStatementList
|
||||
9(10) element: PyExpressionStatement
|
||||
10(11) READ ACCESS: z
|
||||
11() element: null
|
||||
10(12) READ ACCESS: y
|
||||
11(12) ASSERTTYPE ACCESS: null
|
||||
12(13) element: PyExpressionStatement
|
||||
13(14) READ ACCESS: z
|
||||
14() element: null
|
||||
@@ -1,16 +1,17 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyIfStatement
|
||||
2(3,4) READ ACCESS: True
|
||||
3() element: null. Condition: True:false
|
||||
3(13) element: null. Condition: True:false
|
||||
4(5) element: null. Condition: True:true
|
||||
5(6) ASSERTTYPE ACCESS: True
|
||||
6(7) element: PyStatementList
|
||||
7(8) element: PyWhileStatement
|
||||
8(9,10) READ ACCESS: expr
|
||||
9(15) element: null. Condition: expr:false
|
||||
9(16) element: null. Condition: expr:false
|
||||
10(11) element: null. Condition: expr:true
|
||||
11(12) element: PyStatementList
|
||||
12(15) element: PyBreakStatement
|
||||
13(14) element: PyStatementList
|
||||
14(15) element: PyPrintStatement
|
||||
15() element: null
|
||||
12(16) element: PyBreakStatement
|
||||
13(14) ASSERTTYPE ACCESS: null
|
||||
14(15) element: PyStatementList
|
||||
15(16) element: PyPrintStatement
|
||||
16() element: null
|
||||
@@ -1,5 +1,5 @@
|
||||
match 42:
|
||||
case <error descr="Pattern makes remaining case clauses unreachable">x</error>:
|
||||
pass
|
||||
case <warning descr="This code is unreachable">42</warning>:
|
||||
case 42:
|
||||
<warning descr="This code is unreachable">pass</warning>
|
||||
@@ -1,3 +1,3 @@
|
||||
match 42:
|
||||
case <error descr="Pattern makes remaining alternatives unreachable">x</error> | <error descr="Pattern does not bind name x"><warning descr="This code is unreachable">42</warning></error>:
|
||||
case <error descr="Pattern makes remaining alternatives unreachable">x</error> | <error descr="Pattern does not bind name x">42</error>:
|
||||
pass
|
||||
|
||||
@@ -24,7 +24,38 @@ public class PyUnreachableCodeInspectionTest extends PyInspectionTestCase {
|
||||
public void testUnreachable() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON26, () -> doTest());
|
||||
}
|
||||
|
||||
|
||||
// PY-81676
|
||||
public void testUnreachableBranchesAreStillConnected() {
|
||||
// This test ensures that the unreachable branch still
|
||||
// has some edges to and from the main CFG, which allows us
|
||||
// to make an exception for assert_never or assert False
|
||||
doTestByText("""
|
||||
from typing import assert_never
|
||||
|
||||
if False:
|
||||
<warning descr="This code is unreachable">print("actually unreachable")
|
||||
print("actually unreachable")</warning>
|
||||
|
||||
if False:
|
||||
assert False
|
||||
<warning descr="This code is unreachable">print("actually unreachable")</warning>
|
||||
<warning descr="This code is unreachable">print("actually unreachable")</warning>
|
||||
|
||||
def f(obj: int) -> None:
|
||||
match scalar:
|
||||
case <error descr="Pattern makes remaining case clauses unreachable">x</error>:
|
||||
print("everything")
|
||||
case <error descr="Pattern makes remaining case clauses unreachable">_</error>:
|
||||
<warning descr="This code is unreachable">print("actually unreachable")
|
||||
print("actually unreachable")</warning>
|
||||
case _ as unreachable:
|
||||
assert_never(unreachable)
|
||||
<warning descr="This code is unreachable">print("actually unreachable")</warning>
|
||||
<warning descr="This code is unreachable">print("actually unreachable")</warning>
|
||||
""");
|
||||
}
|
||||
|
||||
// PY-82712
|
||||
public void testIfInsideTryExcept() {
|
||||
doTestByText("""
|
||||
@@ -129,6 +160,37 @@ def f():
|
||||
""");
|
||||
}
|
||||
|
||||
// PY-81676
|
||||
public void testTerminatingInBranch() {
|
||||
doTestByText("""
|
||||
from enum import Enum
|
||||
from typing import assert_never
|
||||
|
||||
class Foo(Enum):
|
||||
A = 0
|
||||
B = 1
|
||||
|
||||
def f1(foo: Foo) -> None:
|
||||
if foo is Foo.A:
|
||||
...
|
||||
elif foo is Foo.B:
|
||||
...
|
||||
else:
|
||||
assert_never(foo)
|
||||
<warning descr="This code is unreachable">print("unreachable");</warning>
|
||||
|
||||
def f2(foo: Foo) -> None:
|
||||
match foo:
|
||||
case Foo.A:
|
||||
...
|
||||
case Foo.B:
|
||||
...
|
||||
case _:
|
||||
assert_never(foo)
|
||||
<warning descr="This code is unreachable">print("unreachable");</warning>
|
||||
""");
|
||||
}
|
||||
|
||||
// PY-81674
|
||||
public void testConsecutiveTerminating() {
|
||||
doTestByText("""
|
||||
@@ -161,7 +223,7 @@ class Foo(Enum):
|
||||
A = 0
|
||||
B = 1
|
||||
|
||||
<warning descr="This code is unreachable">print(exit())</warning>
|
||||
print(exit())
|
||||
|
||||
<warning descr="This code is unreachable">def unreachable(foo: Foo) -> None:
|
||||
if foo is Foo.A:
|
||||
|
||||
Reference in New Issue
Block a user