Search in sources :

Example 11 with PyResolveContext

use of com.jetbrains.python.psi.resolve.PyResolveContext in project intellij-community by JetBrains.

the class PyMoveFileHandler method retargetUsages.

@Override
public void retargetUsages(List<UsageInfo> usages, Map<PsiElement, PsiElement> oldToNewMap) {
    final Set<PsiFile> updatedFiles = new HashSet<>();
    for (UsageInfo usage : usages) {
        final PsiElement usageElement = usage.getElement();
        if (usageElement != null) {
            final PsiNamedElement movedElement = usageElement.getCopyableUserData(REFERENCED_ELEMENT);
            usageElement.putCopyableUserData(REFERENCED_ELEMENT, null);
            if (movedElement != null) {
                final PsiFile usageFile = usageElement.getContainingFile();
                final PyImportStatementBase importStmt = PsiTreeUtil.getParentOfType(usageElement, PyImportStatementBase.class);
                // TODO: Retarget qualified expressions in docstrings
                if (importStmt != null) {
                    if (usageFile.getUserData(ORIGINAL_FILE_LOCATION) != null) {
                        // Leave relative imports as they are after #updateRelativeImportsInModule
                        final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(usageFile.getProject(), usageFile);
                        final PyResolveContext resolveContext = PyResolveContext.defaultContext().withTypeEvalContext(typeEvalContext);
                        if (ContainerUtil.getFirstItem(PyUtil.multiResolveTopPriority(usageElement, resolveContext)) == movedElement) {
                            continue;
                        }
                    }
                    updatedFiles.add(usageFile);
                    final boolean usageInsideImportElement = PsiTreeUtil.getParentOfType(usageElement, PyImportElement.class) != null;
                    if (usageInsideImportElement) {
                        // or simple unqualified import of the module (import module).
                        if (PyClassRefactoringUtil.updateUnqualifiedImportOfElement(importStmt, movedElement)) {
                            continue;
                        }
                    }
                    final QualifiedName newElementName = QualifiedNameFinder.findCanonicalImportPath(movedElement, usageElement);
                    if (importStmt instanceof PyFromImportStatement) {
                        if (!usageInsideImportElement) {
                            replaceRelativeImportSourceWithQualifiedExpression((PyFromImportStatement) importStmt, newElementName);
                        }
                    } else {
                        replaceWithQualifiedExpression(usageElement, newElementName);
                    }
                } else if (usageElement instanceof PyReferenceExpression) {
                    updatedFiles.add(usageFile);
                    if (((PyReferenceExpression) usageElement).isQualified()) {
                        final QualifiedName newQualifiedName = QualifiedNameFinder.findCanonicalImportPath(movedElement, usageElement);
                        replaceWithQualifiedExpression(usageElement, newQualifiedName);
                    } else {
                        final QualifiedName newName = QualifiedName.fromComponents(PyClassRefactoringUtil.getOriginalName(movedElement));
                        replaceWithQualifiedExpression(usageElement, newName);
                    }
                }
            }
        }
    }
    if (!updatedFiles.isEmpty()) {
        final PyImportOptimizer optimizer = new PyImportOptimizer();
        for (PsiFile file : updatedFiles) {
            final boolean injectedFragment = InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file);
            if (!injectedFragment) {
                optimizer.processFile(file).run();
            }
        }
    }
}
Also used : PyResolveContext(com.jetbrains.python.psi.resolve.PyResolveContext) QualifiedName(com.intellij.psi.util.QualifiedName) TypeEvalContext(com.jetbrains.python.psi.types.TypeEvalContext) PyImportOptimizer(com.jetbrains.python.codeInsight.imports.PyImportOptimizer) UsageInfo(com.intellij.usageView.UsageInfo)

Example 12 with PyResolveContext

use of com.jetbrains.python.psi.resolve.PyResolveContext in project intellij-community by JetBrains.

the class PyUtil method getReturnTypeOfMember.

@Nullable
public static PyType getReturnTypeOfMember(@NotNull PyType type, @NotNull String memberName, @Nullable PyExpression location, @NotNull TypeEvalContext context) {
    final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
    final List<? extends RatedResolveResult> resolveResults = type.resolveMember(memberName, location, AccessDirection.READ, resolveContext);
    if (resolveResults != null) {
        final List<PyType> types = new ArrayList<>();
        for (RatedResolveResult resolveResult : resolveResults) {
            final PyType returnType = getReturnType(resolveResult.getElement(), context);
            if (returnType != null) {
                types.add(returnType);
            }
        }
        return PyUnionType.union(types);
    }
    return null;
}
Also used : PyResolveContext(com.jetbrains.python.psi.resolve.PyResolveContext) RatedResolveResult(com.jetbrains.python.psi.resolve.RatedResolveResult)

Example 13 with PyResolveContext

use of com.jetbrains.python.psi.resolve.PyResolveContext in project intellij-community by JetBrains.

the class PythonPatterns method multiResolveCalledFunction.

@NotNull
private static List<PyCallable> multiResolveCalledFunction(@Nullable Object expression, @Nullable String functionName, int index) {
    if (!isCallArgument(expression, functionName, index)) {
        return Collections.emptyList();
    }
    final PyCallExpression call = (PyCallExpression) ((PyExpression) expression).getParent().getParent();
    // TODO is it better or worse to allow implicits here?
    final PyResolveContext context = PyResolveContext.noImplicits().withTypeEvalContext(TypeEvalContext.codeAnalysis(call.getProject(), call.getContainingFile()));
    return call.multiResolveCalleeFunction(context);
}
Also used : PyResolveContext(com.jetbrains.python.psi.resolve.PyResolveContext) NotNull(org.jetbrains.annotations.NotNull)

Example 14 with PyResolveContext

use of com.jetbrains.python.psi.resolve.PyResolveContext in project intellij-community by JetBrains.

the class PyBaseElementImpl method findReferenceAt.

/**
   * Overrides the findReferenceAt() logic in order to provide a resolve context with origin file for returned references.
   * The findReferenceAt() is usually invoked from UI operations, and it helps to be able to do deeper analysis in the
   * current file for such operations.
   *
   * @param offset the offset to find the reference at
   * @return the reference or null.
   */
@Override
public PsiReference findReferenceAt(int offset) {
    // copy/paste from SharedPsiElementImplUtil
    PsiElement element = findElementAt(offset);
    if (element == null || element instanceof OuterLanguageElement)
        return null;
    offset = getTextRange().getStartOffset() + offset - element.getTextRange().getStartOffset();
    List<PsiReference> referencesList = new ArrayList<>();
    final PsiFile file = element.getContainingFile();
    final PyResolveContext resolveContext = file != null ? PyResolveContext.defaultContext().withTypeEvalContext(TypeEvalContext.codeAnalysis(file.getProject(), file)) : PyResolveContext.defaultContext();
    while (element != null) {
        addReferences(offset, element, referencesList, resolveContext);
        offset = element.getStartOffsetInParent() + offset;
        if (element instanceof PsiFile)
            break;
        element = element.getParent();
    }
    if (referencesList.isEmpty())
        return null;
    if (referencesList.size() == 1)
        return referencesList.get(0);
    return new PsiMultiReference(referencesList.toArray(new PsiReference[referencesList.size()]), referencesList.get(referencesList.size() - 1).getElement());
}
Also used : OuterLanguageElement(com.intellij.psi.templateLanguages.OuterLanguageElement) PyResolveContext(com.jetbrains.python.psi.resolve.PyResolveContext) ArrayList(java.util.ArrayList) PsiMultiReference(com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference)

Example 15 with PyResolveContext

use of com.jetbrains.python.psi.resolve.PyResolveContext in project intellij-community by JetBrains.

the class PyUnusedLocalInspectionVisitor method isRangeIteration.

private boolean isRangeIteration(@NotNull PyForStatement forStatement) {
    final PyExpression source = forStatement.getForPart().getSource();
    if (!(source instanceof PyCallExpression)) {
        return false;
    }
    final PyCallExpression expr = (PyCallExpression) source;
    if (expr.isCalleeText("range", "xrange")) {
        final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(myTypeEvalContext);
        final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(forStatement);
        return ContainerUtil.exists(expr.multiResolveCalleeFunction(resolveContext), builtinCache::isBuiltin);
    }
    return false;
}
Also used : PyResolveContext(com.jetbrains.python.psi.resolve.PyResolveContext) PyBuiltinCache(com.jetbrains.python.psi.impl.PyBuiltinCache)

Aggregations

PyResolveContext (com.jetbrains.python.psi.resolve.PyResolveContext)27 PsiElement (com.intellij.psi.PsiElement)12 NotNull (org.jetbrains.annotations.NotNull)11 Nullable (org.jetbrains.annotations.Nullable)11 PsiTreeUtil (com.intellij.psi.util.PsiTreeUtil)6 com.jetbrains.python.psi (com.jetbrains.python.psi)6 ContainerUtil (com.intellij.util.containers.ContainerUtil)5 RatedResolveResult (com.jetbrains.python.psi.resolve.RatedResolveResult)5 TypeEvalContext (com.jetbrains.python.psi.types.TypeEvalContext)5 java.util (java.util)5 LookupElement (com.intellij.codeInsight.lookup.LookupElement)4 Extensions (com.intellij.openapi.extensions.Extensions)4 PsiFile (com.intellij.psi.PsiFile)4 ArrayUtil (com.intellij.util.ArrayUtil)4 Processor (com.intellij.util.Processor)4 PyNames (com.jetbrains.python.PyNames)4 Collectors (java.util.stream.Collectors)4 Sets (com.google.common.collect.Sets)3 Pair (com.intellij.openapi.util.Pair)3 QualifiedName (com.intellij.psi.util.QualifiedName)3