@NotNull private static List<RatedResolveResult> resolveInDirectory( @NotNull final String referencedName, @Nullable final PsiFile containingFile, final PsiDirectory dir, boolean isFileOnly, boolean checkForPackage) { final PsiDirectory subdir = dir.findSubdirectory(referencedName); if (subdir != null && (!checkForPackage || PyUtil.isPackage(subdir, containingFile))) { return ResolveResultList.to(subdir); } final PsiFile module = findPyFileInDir(dir, referencedName); if (module != null) { return ResolveResultList.to(module); } if (!isFileOnly) { // not a subdir, not a file; could be a name in parent/__init__.py final PsiFile initPy = dir.findFile(PyNames.INIT_DOT_PY); if (initPy == containingFile) { return Collections.emptyList(); // don't dive into the file we're in } if (initPy instanceof PyFile) { return ((PyFile) initPy).multiResolveName(referencedName); } } return Collections.emptyList(); }
/** * Finds a directory that many levels above a given file, making sure that every level has an * __init__.py. * * @param base file that works as a reference. * @param depth must be positive, 1 means the dir that contains base, 2 is one dir above, etc. * @return found directory, or null. */ @Nullable public static PsiDirectory stepBackFrom(PsiFile base, int depth) { if (depth == 0) { return base.getContainingDirectory(); } PsiDirectory result; if (base != null) { base = base.getOriginalFile(); // just to make sure result = base.getContainingDirectory(); int count = 1; while (result != null && PyUtil.isPackage(result, base)) { if (count >= depth) return result; result = result.getParentDirectory(); count += 1; } } return null; }