@Nullable private PyClass getClassOwner(@Nullable PsiElement element) { for (ScopeOwner owner = ScopeUtil.getScopeOwner(element); owner != null; owner = ScopeUtil.getScopeOwner(owner)) { if (owner instanceof PyClass) { return (PyClass) owner; } } return null; }
@Override public void visitPyTargetExpression(final PyTargetExpression node) { final ScopeOwner owner = ScopeUtil.getScopeOwner(node); if (owner instanceof PyFile || owner instanceof PyClass) { processElement(node); } }
@NotNull @Override public SearchScope getUseScope() { final ScopeOwner scopeOwner = ScopeUtil.getScopeOwner(this); if (scopeOwner instanceof PyFunction) { return new LocalSearchScope(scopeOwner); } return super.getUseScope(); }
private static boolean inConstructor(@NotNull PsiElement expression) { final PsiElement expr = expression instanceof PyClass ? expression : expression.getParent(); PyClass clazz = PyUtil.getContainingClassOrSelf(expr); final ScopeOwner current = ScopeUtil.getScopeOwner(expression); if (clazz != null && current != null && current instanceof PyFunction) { PyFunction init = clazz.findMethodByName(PyNames.INIT, false, null); if (current == init) { return true; } } return false; }
@Override public void visitPyNonlocalStatement(final PyNonlocalStatement node) { for (PyTargetExpression var : node.getVariables()) { final String name = var.getName(); final ScopeOwner owner = ScopeUtil.getDeclarationScopeOwner(var, name); if (owner == null || owner instanceof PyFile) { registerProblem( var, PyBundle.message("INSP.unbound.nonlocal.variable", name), ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } } }
public Object[] getCompletionVariants( String completionPrefix, PsiElement location, ProcessingContext context) { List<LookupElement> result = new ArrayList<LookupElement>(); ScopeOwner scopeOwner = ScopeUtil.getScopeOwner(location); assert scopeOwner != null; final List<PyImportElement> importTargets = PyModuleType.getVisibleImports(scopeOwner); final int imported = myImportedModule.getImportedPrefix().getComponentCount(); for (PyImportElement importTarget : importTargets) { final QualifiedName qName = importTarget.getImportedQName(); if (qName != null && qName.matchesPrefix(myImportedModule.getImportedPrefix())) { final List<String> components = qName.getComponents(); if (components.size() > imported) { String module = components.get(imported); result.add(LookupElementBuilder.create(module)); } } } return result.toArray(new Object[result.size()]); }
@Nullable public PyType getQualifiedReferenceTypeByControlFlow(@NotNull TypeEvalContext context) { PyExpression qualifier = getQualifier(); if (context.allowDataFlow(this) && qualifier != null) { PyExpression next = qualifier; while (next != null) { qualifier = next; next = qualifier instanceof PyQualifiedExpression ? ((PyQualifiedExpression) qualifier).getQualifier() : null; } final ScopeOwner scopeOwner = ScopeUtil.getScopeOwner(this); final QualifiedName qname = asQualifiedName(); if (qname != null && scopeOwner != null) { return getTypeByControlFlow(qname.toString(), context, qualifier, scopeOwner); } } return null; }
private void processElement(@NotNull final PsiNameIdentifierOwner element) { if (isConditional(element)) { return; } final String name = element.getName(); final ScopeOwner owner = ScopeUtil.getScopeOwner(element); if (owner != null && name != null) { final Instruction[] instructions = ControlFlowCache.getControlFlow(owner).getInstructions(); PsiElement elementInControlFlow = element; if (element instanceof PyTargetExpression) { final PyImportStatement importStatement = PsiTreeUtil.getParentOfType(element, PyImportStatement.class); if (importStatement != null) { elementInControlFlow = importStatement; } } final int startInstruction = ControlFlowUtil.findInstructionNumberByElement(instructions, elementInControlFlow); if (startInstruction < 0) { return; } final Ref<PsiElement> readElementRef = Ref.create(null); final Ref<PsiElement> writeElementRef = Ref.create(null); ControlFlowUtil.iteratePrev( startInstruction, instructions, new Function<Instruction, ControlFlowUtil.Operation>() { @Override public ControlFlowUtil.Operation fun(Instruction instruction) { if (instruction instanceof ReadWriteInstruction && instruction.num() != startInstruction) { final ReadWriteInstruction rwInstruction = (ReadWriteInstruction) instruction; if (name.equals(rwInstruction.getName())) { final PsiElement originalElement = rwInstruction.getElement(); if (originalElement != null) { if (rwInstruction.getAccess().isReadAccess()) { readElementRef.set(originalElement); } if (rwInstruction.getAccess().isWriteAccess()) { if (originalElement != element) { writeElementRef.set(originalElement); } } } return ControlFlowUtil.Operation.CONTINUE; } } return ControlFlowUtil.Operation.NEXT; } }); final PsiElement writeElement = writeElementRef.get(); if (writeElement != null && readElementRef.get() == null) { final List<LocalQuickFix> quickFixes = new ArrayList<LocalQuickFix>(); if (suggestRename(element, writeElement)) { quickFixes.add(new PyRenameElementQuickFix()); } final PsiElement identifier = element.getNameIdentifier(); registerProblem( identifier != null ? identifier : element, PyBundle.message("INSP.redeclared.name", name), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, null, quickFixes.toArray(new LocalQuickFix[quickFixes.size()])); } } }
@Override public void visitPyReferenceExpression(final PyReferenceExpression node) { if (node.getContainingFile() instanceof PyExpressionCodeFragment) { return; } // Ignore global statements arguments if (PyGlobalStatementNavigator.getByArgument(node) != null) { return; } // Ignore qualifier inspections if (node.getQualifier() != null) { return; } // Ignore import subelements if (PsiTreeUtil.getParentOfType(node, PyImportStatementBase.class) != null) { return; } final String name = node.getReferencedName(); if (name == null) { return; } final ScopeOwner owner = ScopeUtil.getDeclarationScopeOwner(node, name); final Set<ScopeOwner> largeFunctions = getSession().getUserData(LARGE_FUNCTIONS_KEY); assert largeFunctions != null; if (owner == null || largeFunctions.contains(owner)) { return; } // Ignore references declared in outer scopes if (owner != ScopeUtil.getScopeOwner(node)) { return; } final Scope scope = ControlFlowCache.getScope(owner); // Ignore globals and if scope even doesn't contain such a declaration if (scope.isGlobal(name) || (!scope.containsDeclaration(name))) { return; } // Start DFA from the assignment statement in case of augmented assignments final PsiElement anchor; final PyAugAssignmentStatement augAssignment = PsiTreeUtil.getParentOfType(node, PyAugAssignmentStatement.class); if (augAssignment != null && name.equals(augAssignment.getTarget().getName())) { anchor = augAssignment; } else { anchor = node; } final ScopeVariable variable; try { variable = scope.getDeclaredVariable(anchor, name); } catch (DFALimitExceededException e) { largeFunctions.add(owner); registerLargeFunction(owner); return; } if (variable == null) { if (!isFirstUnboundRead(node, owner)) { return; } final PsiPolyVariantReference ref = node.getReference(resolveWithoutImplicits()); if (ref == null) { return; } final PsiElement resolved = ref.resolve(); final boolean isBuiltin = PyBuiltinCache.getInstance(node).hasInBuiltins(resolved); if (owner instanceof PyClass) { if (isBuiltin || ScopeUtil.getDeclarationScopeOwner(owner, name) != null) { return; } } if (PyUnreachableCodeInspection.hasAnyInterruptedControlFlowPaths(node)) { return; } if (owner instanceof PyFile) { if (isBuiltin) { return; } if (resolved != null && !PyUtil.inSameFile(node, resolved)) { return; } registerProblem(node, PyBundle.message("INSP.unbound.name.not.defined", name)); } else { registerProblem( node, PyBundle.message("INSP.unbound.local.variable", node.getName()), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, null, new AddGlobalQuickFix()); } } }
protected List<PsiElement> getOccurrences( PsiElement element, @NotNull final PyExpression expression) { return PyRefactoringUtil.getOccurrences(expression, ScopeUtil.getScopeOwner(expression)); }