Search in sources :

Example 11 with PyType

use of com.jetbrains.python.psi.types.PyType in project intellij-community by JetBrains.

the class AddFunctionQuickFix method applyFix.

public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
    try {
        final PsiElement problemElement = descriptor.getPsiElement();
        if (!(problemElement instanceof PyQualifiedExpression))
            return;
        final PyExpression qualifier = ((PyQualifiedExpression) problemElement).getQualifier();
        if (qualifier == null)
            return;
        final PyType type = TypeEvalContext.userInitiated(problemElement.getProject(), problemElement.getContainingFile()).getType(qualifier);
        if (!(type instanceof PyModuleType))
            return;
        final PyFile file = ((PyModuleType) type).getModule();
        sure(file);
        sure(FileModificationService.getInstance().preparePsiElementForWrite(file));
        // try to at least match parameter count
        // TODO: get parameter style from code style
        PyFunctionBuilder builder = new PyFunctionBuilder(myIdentifier, problemElement);
        PsiElement problemParent = problemElement.getParent();
        if (problemParent instanceof PyCallExpression) {
            PyArgumentList arglist = ((PyCallExpression) problemParent).getArgumentList();
            if (arglist == null)
                return;
            final PyExpression[] args = arglist.getArguments();
            for (PyExpression arg : args) {
                if (arg instanceof PyKeywordArgument) {
                    // foo(bar) -> def foo(bar_1)
                    builder.parameter(((PyKeywordArgument) arg).getKeyword());
                } else if (arg instanceof PyReferenceExpression) {
                    PyReferenceExpression refex = (PyReferenceExpression) arg;
                    builder.parameter(refex.getReferencedName());
                } else {
                    // use a boring name
                    builder.parameter("param");
                }
            }
        } else if (problemParent != null) {
            for (PyInspectionExtension extension : Extensions.getExtensions(PyInspectionExtension.EP_NAME)) {
                List<String> params = extension.getFunctionParametersFromUsage(problemElement);
                if (params != null) {
                    for (String param : params) {
                        builder.parameter(param);
                    }
                    break;
                }
            }
        }
        // else: no arglist, use empty args
        PyFunction function = builder.buildFunction(project, LanguageLevel.forElement(file));
        // add to the bottom
        function = (PyFunction) file.add(function);
        showTemplateBuilder(function, file);
    } catch (IncorrectOperationException ignored) {
        // we failed. tell about this
        PyUtil.showBalloon(project, PyBundle.message("QFIX.failed.to.add.function"), MessageType.ERROR);
    }
}
Also used : PyInspectionExtension(com.jetbrains.python.inspections.PyInspectionExtension) PyType(com.jetbrains.python.psi.types.PyType) PyFunctionBuilder(com.jetbrains.python.psi.impl.PyFunctionBuilder) List(java.util.List) IncorrectOperationException(com.intellij.util.IncorrectOperationException) PsiElement(com.intellij.psi.PsiElement) PyModuleType(com.jetbrains.python.psi.types.PyModuleType)

Example 12 with PyType

use of com.jetbrains.python.psi.types.PyType in project intellij-community by JetBrains.

the class PyUsageTypeProvider method getUsageType.

public UsageType getUsageType(PsiElement element, @NotNull UsageTarget[] targets) {
    if (element instanceof PyElement) {
        if (PsiTreeUtil.getParentOfType(element, PyImportStatementBase.class) != null) {
            return IN_IMPORT;
        }
        if (element instanceof PyQualifiedExpression) {
            final PyExpression qualifier = ((PyQualifiedExpression) element).getQualifier();
            if (qualifier != null) {
                final TypeEvalContext context = TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile());
                final PyType type = context.getType(qualifier);
                if (type == null || type instanceof PyStructuralType) {
                    return UNTYPED;
                }
            }
        }
        if (element instanceof PyReferenceExpression) {
            final PyCallExpression call = PsiTreeUtil.getParentOfType(element, PyCallExpression.class);
            if (call != null && call.isCalleeText(PyNames.ISINSTANCE)) {
                final PyExpression[] args = call.getArguments();
                if (args.length == 2) {
                    PyExpression typeExpression = args[1];
                    if (element == typeExpression) {
                        return USAGE_IN_ISINSTANCE;
                    }
                    typeExpression = PyPsiUtils.flattenParens(typeExpression);
                    if (typeExpression instanceof PySequenceExpression && element.getParent() == typeExpression) {
                        return USAGE_IN_ISINSTANCE;
                    }
                }
            }
            final PyClass pyClass = PsiTreeUtil.getParentOfType(element, PyClass.class);
            if (pyClass != null && PsiTreeUtil.isAncestor(pyClass.getSuperClassExpressionList(), element, true)) {
                return USAGE_IN_SUPERCLASS;
            }
        }
    }
    return null;
}
Also used : PyType(com.jetbrains.python.psi.types.PyType) PyStructuralType(com.jetbrains.python.psi.types.PyStructuralType) TypeEvalContext(com.jetbrains.python.psi.types.TypeEvalContext)

Example 13 with PyType

use of com.jetbrains.python.psi.types.PyType in project intellij-community by JetBrains.

the class PyDictKeyNamesCompletionContributor method addDictConstructorKeys.

/**
   * add keys to completion result from dict constructor
   */
private static void addDictConstructorKeys(final PyCallExpression dictConstructor, final CompletionResultSet result) {
    final PyExpression callee = dictConstructor.getCallee();
    if (callee == null)
        return;
    final String name = callee.getText();
    if ("dict".equals(name)) {
        final TypeEvalContext context = TypeEvalContext.codeCompletion(callee.getProject(), callee.getContainingFile());
        final PyType type = context.getType(dictConstructor);
        if (type != null && type.isBuiltin()) {
            final PyArgumentList list = dictConstructor.getArgumentList();
            if (list == null)
                return;
            final PyExpression[] argumentList = list.getArguments();
            for (final PyExpression argument : argumentList) {
                if (argument instanceof PyKeywordArgument) {
                    result.addElement(createElement("'" + ((PyKeywordArgument) argument).getKeyword() + "'"));
                }
            }
        }
    }
}
Also used : PyType(com.jetbrains.python.psi.types.PyType) TypeEvalContext(com.jetbrains.python.psi.types.TypeEvalContext)

Example 14 with PyType

use of com.jetbrains.python.psi.types.PyType in project intellij-community by JetBrains.

the class IntroduceHandler method generateSuggestedNames.

protected Collection<String> generateSuggestedNames(PyExpression expression) {
    Collection<String> candidates = new LinkedHashSet<String>() {

        @Override
        public boolean add(String s) {
            if (PyNames.isReserved(s)) {
                return false;
            }
            return super.add(s);
        }
    };
    String text = expression.getText();
    final Pair<PsiElement, TextRange> selection = expression.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE);
    if (selection != null) {
        text = selection.getSecond().substring(selection.getFirst().getText());
    }
    if (expression instanceof PyCallExpression) {
        final PyExpression callee = ((PyCallExpression) expression).getCallee();
        if (callee != null) {
            text = callee.getText();
        }
    }
    if (text != null) {
        candidates.addAll(NameSuggesterUtil.generateNames(text));
    }
    final TypeEvalContext context = TypeEvalContext.userInitiated(expression.getProject(), expression.getContainingFile());
    PyType type = context.getType(expression);
    if (type != null && type != PyNoneType.INSTANCE) {
        String typeName = type.getName();
        if (typeName != null) {
            if (type.isBuiltin()) {
                typeName = typeName.substring(0, 1);
            }
            candidates.addAll(NameSuggesterUtil.generateNamesByType(typeName));
        }
    }
    final PyKeywordArgument kwArg = PsiTreeUtil.getParentOfType(expression, PyKeywordArgument.class);
    if (kwArg != null && kwArg.getValueExpression() == expression) {
        candidates.add(kwArg.getKeyword());
    }
    Optional.ofNullable(PsiTreeUtil.getParentOfType(expression, PyArgumentList.class)).map(PyArgumentList::getCallExpression).ifPresent(call -> StreamEx.of(call.multiMapArguments(PyResolveContext.noImplicits())).map(mapping -> mapping.getMappedParameters().get(expression)).nonNull().map(PyNamedParameter::getName).forEach(candidates::add));
    return candidates;
}
Also used : TextRange(com.intellij.openapi.util.TextRange) TypeEvalContext(com.jetbrains.python.psi.types.TypeEvalContext) PyType(com.jetbrains.python.psi.types.PyType)

Example 15 with PyType

use of com.jetbrains.python.psi.types.PyType in project intellij-community by JetBrains.

the class NumpyDocStringTypeProvider method getCallType.

@Nullable
@Override
public Ref<PyType> getCallType(@NotNull PyFunction function, @Nullable PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
    if (isApplicable(function)) {
        final PyExpression callee = callSite instanceof PyCallExpression ? ((PyCallExpression) callSite).getCallee() : null;
        final NumpyDocString docString = forFunction(function, callee);
        if (docString != null) {
            final List<SectionField> returns = docString.getReturnFields();
            final PyPsiFacade facade = getPsiFacade(function);
            switch(returns.size()) {
                case 0:
                    return null;
                case 1:
                    // Function returns single value
                    return Optional.ofNullable(returns.get(0).getType()).filter(StringUtil::isNotEmpty).map(typeName -> isUfuncType(function, typeName) ? facade.parseTypeAnnotation("T", function) : parseNumpyDocType(function, typeName)).map(Ref::create).orElse(null);
                default:
                    // Function returns a tuple
                    final List<PyType> unionMembers = new ArrayList<>();
                    final List<PyType> members = new ArrayList<>();
                    for (int i = 0; i < returns.size(); i++) {
                        final String memberTypeName = returns.get(i).getType();
                        final PyType returnType = StringUtil.isNotEmpty(memberTypeName) ? parseNumpyDocType(function, memberTypeName) : null;
                        final boolean isOptional = StringUtil.isNotEmpty(memberTypeName) && memberTypeName.contains("optional");
                        if (isOptional && i != 0) {
                            if (members.size() > 1) {
                                unionMembers.add(facade.createTupleType(members, function));
                            } else if (members.size() == 1) {
                                unionMembers.add(members.get(0));
                            }
                        }
                        members.add(returnType);
                        if (i == returns.size() - 1 && isOptional) {
                            unionMembers.add(facade.createTupleType(members, function));
                        }
                    }
                    final PyType type = unionMembers.isEmpty() ? facade.createTupleType(members, function) : facade.createUnionType(unionMembers);
                    return Ref.create(type);
            }
        }
    }
    return null;
}
Also used : PyType(com.jetbrains.python.psi.types.PyType) SectionField(com.jetbrains.python.documentation.docstrings.SectionBasedDocString.SectionField) NumpyDocString(com.jetbrains.python.documentation.docstrings.NumpyDocString) NumpyDocString(com.jetbrains.python.documentation.docstrings.NumpyDocString) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

PyType (com.jetbrains.python.psi.types.PyType)42 TypeEvalContext (com.jetbrains.python.psi.types.TypeEvalContext)13 PsiElement (com.intellij.psi.PsiElement)11 Nullable (org.jetbrains.annotations.Nullable)9 PyClassType (com.jetbrains.python.psi.types.PyClassType)6 NotNull (org.jetbrains.annotations.NotNull)6 PsiFile (com.intellij.psi.PsiFile)5 ArrayList (java.util.ArrayList)5 PyClassLikeType (com.jetbrains.python.psi.types.PyClassLikeType)4 PyClassTypeImpl (com.jetbrains.python.psi.types.PyClassTypeImpl)4 NumpyDocString (com.jetbrains.python.documentation.docstrings.NumpyDocString)3 PyExpression (com.jetbrains.python.psi.PyExpression)3 FileASTNode (com.intellij.lang.FileASTNode)2 TextRange (com.intellij.openapi.util.TextRange)2 PsiReference (com.intellij.psi.PsiReference)2 IncorrectOperationException (com.intellij.util.IncorrectOperationException)2 ScopeOwner (com.jetbrains.python.codeInsight.controlflow.ScopeOwner)2 PyClass (com.jetbrains.python.psi.PyClass)2 PyFunctionBuilder (com.jetbrains.python.psi.impl.PyFunctionBuilder)2 PyStructuralType (com.jetbrains.python.psi.types.PyStructuralType)2