Search in sources :

Example 21 with TypeEvalContext

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));
    }
}
Also used : TypeEvalContext(com.jetbrains.python.psi.types.TypeEvalContext) PyNames(com.jetbrains.python.PyNames) java.util(java.util) LocalInspectionToolSession(com.intellij.codeInspection.LocalInspectionToolSession) PsiTreeUtil(com.intellij.psi.util.PsiTreeUtil) Lists(com.google.common.collect.Lists) Nls(org.jetbrains.annotations.Nls) com.jetbrains.python.psi(com.jetbrains.python.psi) LocalQuickFix(com.intellij.codeInspection.LocalQuickFix) PsiElementVisitor(com.intellij.psi.PsiElementVisitor) ProblemsHolder(com.intellij.codeInspection.ProblemsHolder) PyBundle(com.jetbrains.python.PyBundle) PyTypeChecker(com.jetbrains.python.psi.types.PyTypeChecker) PyType(com.jetbrains.python.psi.types.PyType) PsiPolyVariantReference(com.intellij.psi.PsiPolyVariantReference) PyTokenTypes(com.jetbrains.python.PyTokenTypes) PyResolveContext(com.jetbrains.python.psi.resolve.PyResolveContext) PyRemoveArgumentQuickFix(com.jetbrains.python.inspections.quickfix.PyRemoveArgumentQuickFix) Collectors(java.util.stream.Collectors) ASTNode(com.intellij.lang.ASTNode) Nullable(org.jetbrains.annotations.Nullable) ResolveResult(com.intellij.psi.ResolveResult) PyRenameArgumentQuickFix(com.jetbrains.python.inspections.quickfix.PyRenameArgumentQuickFix) PyABCUtil(com.jetbrains.python.psi.types.PyABCUtil) StreamEx(one.util.streamex.StreamEx) XmlStringUtil(com.intellij.xml.util.XmlStringUtil) NotNull(org.jetbrains.annotations.NotNull) PyRenameArgumentQuickFix(com.jetbrains.python.inspections.quickfix.PyRenameArgumentQuickFix) LocalQuickFix(com.intellij.codeInspection.LocalQuickFix) PyRemoveArgumentQuickFix(com.jetbrains.python.inspections.quickfix.PyRemoveArgumentQuickFix)

Example 22 with TypeEvalContext

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;
}
Also used : ChainIterable(com.jetbrains.python.toolbox.ChainIterable) TypeEvalContext(com.jetbrains.python.psi.types.TypeEvalContext) NotNull(org.jetbrains.annotations.NotNull)

Example 23 with TypeEvalContext

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);
}
Also used : TypeEvalContext(com.jetbrains.python.psi.types.TypeEvalContext)

Example 24 with TypeEvalContext

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);
}
Also used : TypeEvalContext(com.jetbrains.python.psi.types.TypeEvalContext) PyNames(com.jetbrains.python.PyNames) PythonDocumentationProvider(com.jetbrains.python.documentation.PythonDocumentationProvider) PyType(com.jetbrains.python.psi.types.PyType) StringUtil(com.intellij.openapi.util.text.StringUtil) Predicate(java.util.function.Predicate) PyClassLikeType(com.jetbrains.python.psi.types.PyClassLikeType) Set(java.util.Set) ContainerUtil(com.intellij.util.containers.ContainerUtil) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Nullable(org.jetbrains.annotations.Nullable) List(java.util.List) PsiElement(com.intellij.psi.PsiElement) XmlStringUtil(com.intellij.xml.util.XmlStringUtil) com.jetbrains.python.psi(com.jetbrains.python.psi) Optional(java.util.Optional) ObjectUtils(com.intellij.util.ObjectUtils) PyStructuralType(com.jetbrains.python.psi.types.PyStructuralType) ProblemHighlightType(com.intellij.codeInspection.ProblemHighlightType) NotNull(org.jetbrains.annotations.NotNull) Sets(com.google.common.collect.Sets) PyType(com.jetbrains.python.psi.types.PyType) PyStructuralType(com.jetbrains.python.psi.types.PyStructuralType) NotNull(org.jetbrains.annotations.NotNull)

Example 25 with TypeEvalContext

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;
}
Also used : TypeEvalContext(com.jetbrains.python.psi.types.TypeEvalContext) ScopeOwner(com.jetbrains.python.codeInsight.controlflow.ScopeOwner)

Aggregations

TypeEvalContext (com.jetbrains.python.psi.types.TypeEvalContext)44 PyType (com.jetbrains.python.psi.types.PyType)15 PsiElement (com.intellij.psi.PsiElement)13 NotNull (org.jetbrains.annotations.NotNull)10 Nullable (org.jetbrains.annotations.Nullable)8 PyResolveContext (com.jetbrains.python.psi.resolve.PyResolveContext)6 PyClassLikeType (com.jetbrains.python.psi.types.PyClassLikeType)5 ArrayList (java.util.ArrayList)5 ScopeOwner (com.jetbrains.python.codeInsight.controlflow.ScopeOwner)4 com.jetbrains.python.psi (com.jetbrains.python.psi)4 TextRange (com.intellij.openapi.util.TextRange)3 PsiTreeUtil (com.intellij.psi.util.PsiTreeUtil)3 XmlStringUtil (com.intellij.xml.util.XmlStringUtil)3 PyNames (com.jetbrains.python.PyNames)3 PyFunction (com.jetbrains.python.psi.PyFunction)3 PyClassType (com.jetbrains.python.psi.types.PyClassType)3 Lists (com.google.common.collect.Lists)2 Instruction (com.intellij.codeInsight.controlflow.Instruction)2 LookupElement (com.intellij.codeInsight.lookup.LookupElement)2 ASTNode (com.intellij.lang.ASTNode)2