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();
}
}
}
}
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;
}
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);
}
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());
}
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;
}
Aggregations