use of com.jetbrains.python.psi.types.TypeEvalContext in project intellij-community by JetBrains.
the class PyArgumentListInspection method highlightUnexpectedArguments.
private static void highlightUnexpectedArguments(@NotNull PyArgumentList node, @NotNull ProblemsHolder holder, @NotNull List<PyCallExpression.PyArgumentsMapping> mappings, @NotNull TypeEvalContext context) {
if (mappings.isEmpty() || mappings.stream().anyMatch(mapping -> mapping.getUnmappedArguments().isEmpty()))
return;
if (mappings.size() == 1) {
// if there is only one mapping, we could suggest quick fixes
final Set<String> duplicateKeywords = getDuplicateKeywordArguments(node);
for (PyExpression argument : mappings.get(0).getUnmappedArguments()) {
final List<LocalQuickFix> quickFixes = Lists.newArrayList(new PyRemoveArgumentQuickFix());
if (argument instanceof PyKeywordArgument) {
if (duplicateKeywords.contains(((PyKeywordArgument) argument).getKeyword())) {
continue;
}
quickFixes.add(new PyRenameArgumentQuickFix());
}
holder.registerProblem(argument, PyBundle.message("INSP.unexpected.arg"), quickFixes.toArray(new LocalQuickFix[quickFixes.size() - 1]));
}
} else {
// all mappings have unmapped arguments so we couldn't determine desired argument list and suggest appropriate quick fixes
holder.registerProblem(node, addPossibleCalleesRepresentationAndWrapInHtml(PyBundle.message("INSP.unexpected.arg(s)"), mappings, context));
}
}
use of com.jetbrains.python.psi.types.TypeEvalContext in project intellij-community by JetBrains.
the class PythonDocumentationProvider method describeFunction.
/**
* Creates a HTML description of function definition.
*
* @param fun the function
* @param funcNameWrapper puts a tag around the function name
* @param escaper sanitizes values that come directly from doc string or code
* @return chain of strings for further chaining
*/
@NotNull
static ChainIterable<String> describeFunction(@NotNull PyFunction fun, FP.Lambda1<Iterable<String>, Iterable<String>> funcNameWrapper, @NotNull FP.Lambda1<String, String> escaper) {
final ChainIterable<String> cat = new ChainIterable<>();
final String name = fun.getName();
cat.addItem("def ").addWith(funcNameWrapper, $(name));
final TypeEvalContext context = TypeEvalContext.userInitiated(fun.getProject(), fun.getContainingFile());
final List<PyParameter> parameters = PyUtil.getParameters(fun, context);
final String paramStr = "(" + StringUtil.join(parameters, parameter -> PyUtil.getReadableRepr(parameter, false), ", ") + ")";
cat.addItem(escaper.apply(paramStr));
if (!PyNames.INIT.equals(name)) {
cat.addItem(escaper.apply("\nInferred type: "));
describeTypeWithLinks(fun, cat);
cat.addItem(BR);
}
return cat;
}
use of com.jetbrains.python.psi.types.TypeEvalContext in project intellij-community by JetBrains.
the class PythonDocumentationProvider method describeTypeWithLinks.
private static void describeTypeWithLinks(@NotNull PyTypedElement element, @NotNull ChainIterable<String> body) {
final TypeEvalContext context = TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile());
describeTypeWithLinks(context.getType(element), context, element, body);
}
use of com.jetbrains.python.psi.types.TypeEvalContext in project intellij-community by JetBrains.
the class PyTypeCheckerInspectionProblemRegistrar method getSingleCalleeProblemMessage.
@NotNull
private static String getSingleCalleeProblemMessage(@NotNull PyTypeCheckerInspection.AnalyzeArgumentResult argumentResult, @NotNull TypeEvalContext context) {
final PyType actualType = argumentResult.getActualType();
final PyType expectedType = argumentResult.getExpectedType();
// see PyTypeCheckerInspection.Visitor.analyzeArgument()
assert actualType != null;
// see PyTypeCheckerInspection.Visitor.analyzeArgument()
assert expectedType != null;
final String actualTypeName = PythonDocumentationProvider.getTypeName(actualType, context);
if (expectedType instanceof PyStructuralType) {
final Set<String> expectedAttributes = ((PyStructuralType) expectedType).getAttributeNames();
final Set<String> actualAttributes = getAttributes(actualType, context);
if (actualAttributes != null) {
final Sets.SetView<String> missingAttributes = Sets.difference(expectedAttributes, actualAttributes);
if (missingAttributes.size() == 1) {
return String.format("Type '%s' doesn't have expected attribute '%s'", actualTypeName, missingAttributes.iterator().next());
} else {
return String.format("Type '%s' doesn't have expected attributes %s", actualTypeName, StringUtil.join(missingAttributes, s -> String.format("'%s'", s), ", "));
}
}
}
final String expectedTypeRepresentation = getSingleCalleeExpectedTypeRepresentation(expectedType, argumentResult.getExpectedTypeAfterSubstitution(), context);
return String.format("Expected type %s, got '%s' instead", expectedTypeRepresentation, actualTypeName);
}
use of com.jetbrains.python.psi.types.TypeEvalContext in project intellij-community by JetBrains.
the class PyReferenceImpl method isReferenceTo.
@Override
public boolean isReferenceTo(PsiElement element) {
if (element instanceof PsiFileSystemItem) {
// may be import via alias, so don't check if names match, do simple resolve check instead
PsiElement resolveResult = resolve();
if (resolveResult instanceof PyImportedModule) {
resolveResult = resolveResult.getNavigationElement();
}
if (element instanceof PsiDirectory) {
if (resolveResult instanceof PyFile) {
final PyFile file = (PyFile) resolveResult;
if (PyUtil.isPackage(file) && file.getContainingDirectory() == element) {
return true;
}
} else if (resolveResult instanceof PsiDirectory) {
final PsiDirectory directory = (PsiDirectory) resolveResult;
if (PyUtil.isPackage(directory, null) && directory == element) {
return true;
}
}
}
return resolveResult == element;
}
if (element instanceof PsiNamedElement) {
final String elementName = ((PsiNamedElement) element).getName();
if ((Comparing.equal(myElement.getReferencedName(), elementName) || PyNames.INIT.equals(elementName))) {
if (!haveQualifiers(element)) {
final ScopeOwner ourScopeOwner = ScopeUtil.getScopeOwner(getElement());
final ScopeOwner theirScopeOwner = ScopeUtil.getScopeOwner(element);
if (element instanceof PyParameter || element instanceof PyTargetExpression) {
// Check if the reference is in the same or inner scope of the element scope, not shadowed by an intermediate declaration
if (resolvesToSameLocal(element, elementName, ourScopeOwner, theirScopeOwner)) {
return true;
}
}
final PsiElement resolveResult = resolve();
if (resolveResult == element) {
return true;
}
// we shadow their name or they shadow ours (PY-6241)
if (resolveResult instanceof PsiNamedElement && resolveResult instanceof ScopeOwner && element instanceof ScopeOwner && theirScopeOwner == ScopeUtil.getScopeOwner(resolveResult)) {
return true;
}
if (!haveQualifiers(element) && ourScopeOwner != null && theirScopeOwner != null) {
if (resolvesToSameGlobal(element, elementName, ourScopeOwner, theirScopeOwner, resolveResult))
return true;
}
if (resolvesToWrapper(element, resolveResult)) {
return true;
}
}
if (element instanceof PyExpression) {
final PyExpression expr = (PyExpression) element;
if (PyUtil.isClassAttribute(myElement) && (PyUtil.isClassAttribute(expr) || PyUtil.isInstanceAttribute(expr))) {
final PyClass c1 = PsiTreeUtil.getParentOfType(element, PyClass.class);
final PyClass c2 = PsiTreeUtil.getParentOfType(myElement, PyClass.class);
final TypeEvalContext context = myContext.getTypeEvalContext();
if (c1 != null && c2 != null && (c1.isSubclass(c2, context) || c2.isSubclass(c1, context))) {
return true;
}
}
}
}
}
return false;
}
Aggregations