@Nullable @Override public List<? extends RatedResolveResult> resolveMember( @NotNull String name, @Nullable PyExpression location, @NotNull AccessDirection direction, @NotNull PyResolveContext resolveContext) { final PsiElement resolved = myImportedModule.resolve(); if (resolved != null) { final PsiFile containingFile = location != null ? location.getContainingFile() : null; List<PsiElement> elements = Collections.singletonList( ResolveImportUtil.resolveChild(resolved, name, containingFile, false, true)); final PyImportElement importElement = myImportedModule.getImportElement(); final PyFile resolvedFile = PyUtil.as(resolved, PyFile.class); if (location != null && importElement != null && PyUtil.inSameFile(location, importElement) && ResolveImportUtil.getPointInImport(location) == PointInImport.NONE && resolved instanceof PsiFileSystemItem && (resolvedFile == null || !PyUtil.isPackage(resolvedFile) || resolvedFile.getElementNamed(name) == null)) { final List<PsiElement> importedSubmodules = PyModuleType.collectImportedSubmodules((PsiFileSystemItem) resolved, location); if (importedSubmodules != null) { final Set<PsiElement> imported = Sets.newHashSet(importedSubmodules); elements = ContainerUtil.filter( elements, new Condition<PsiElement>() { @Override public boolean value(PsiElement element) { return imported.contains(element); } }); } } return ResolveImportUtil.rateResults(elements); } return null; }
@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()); } } }