@Nullable @Override public PyType getReturnType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) { final PyType returnType = typeProvider.getReturnType(this, context); if (returnType != null) { returnType.assertValid(typeProvider.toString()); return returnType; } } if (context.maySwitchToAST(this) && LanguageLevel.forElement(this).isAtLeast(LanguageLevel.PYTHON30)) { PyAnnotation anno = getAnnotation(); if (anno != null) { PyClass pyClass = anno.resolveToClass(); if (pyClass != null) { return new PyClassTypeImpl(pyClass, false); } } } final PyType docStringType = getReturnTypeFromDocString(); if (docStringType != null) { docStringType.assertValid("from docstring"); return docStringType; } if (context.allowReturnTypes(this)) { final Ref<? extends PyType> yieldTypeRef = getYieldStatementType(context); if (yieldTypeRef != null) { return yieldTypeRef.get(); } return getReturnStatementType(context); } return null; }
@Nullable private PyType getGenericReturnType( @NotNull TypeEvalContext typeEvalContext, @Nullable PyQualifiedExpression callSite) { if (typeEvalContext.maySwitchToAST(this) && LanguageLevel.forElement(this).isAtLeast(LanguageLevel.PYTHON30)) { PyAnnotation anno = getAnnotation(); if (anno != null) { PyClass pyClass = anno.resolveToClass(); if (pyClass != null) { return new PyClassTypeImpl(pyClass, false); } } } for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) { final PyType returnType = typeProvider.getReturnType(this, callSite, typeEvalContext); if (returnType != null) { returnType.assertValid(typeProvider.toString()); return returnType; } } final PyType docStringType = getReturnTypeFromDocString(); if (docStringType != null) { docStringType.assertValid("from docstring"); return docStringType; } if (typeEvalContext.allowReturnTypes(this)) { final PyType yieldType = getYieldStatementType(typeEvalContext); if (yieldType != null) { return yieldType; } return getReturnStatementType(typeEvalContext); } return null; }
@Nullable private PyType getReturnType(@NotNull TypeEvalContext context) { for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) { final Ref<PyType> returnTypeRef = typeProvider.getReturnType(this, context); if (returnTypeRef != null) { final PyType returnType = returnTypeRef.get(); if (returnType != null) { returnType.assertValid(typeProvider.toString()); } return returnType; } } final PyType docStringType = getReturnTypeFromDocString(); if (docStringType != null) { docStringType.assertValid("from docstring"); return docStringType; } if (context.allowReturnTypes(this)) { final Ref<? extends PyType> yieldTypeRef = getYieldStatementType(context); if (yieldTypeRef != null) { return yieldTypeRef.get(); } return getReturnStatementType(context); } return null; }
/** * Adds type and description representation from function docstring * * @param parameter parameter of a function * @return true if type from docstring was added */ private boolean addTypeAndDescriptionFromDocstring(@NotNull final PyNamedParameter parameter) { final PyFunction function = PsiTreeUtil.getParentOfType(parameter, PyFunction.class); if (function != null) { final String docString = PyPsiUtils.strValue(function.getDocStringExpression()); final Pair<String, String> typeAndDescr = getTypeAndDescription(docString, parameter); final String type = typeAndDescr.first; final String description = typeAndDescr.second; if (type != null) { final PyType pyType = PyTypeParser.getTypeByName(parameter, type); if (pyType instanceof PyClassType) { myBody .addItem(": ") .addWith( new LinkWrapper(PythonDocumentationProvider.LINK_TYPE_PARAM), $(pyType.getName())); } else { myBody.addItem(": ").addItem(type); } } if (description != null) { myEpilog.addItem(BR).addItem(description); } return type != null; } return false; }
private static void highlightStarArgumentTypeMismatch( PyArgumentList node, ProblemsHolder holder, TypeEvalContext context) { for (PyExpression arg : node.getArguments()) { if (arg instanceof PyStarArgument) { PyExpression content = PyUtil.peelArgument(PsiTreeUtil.findChildOfType(arg, PyExpression.class)); if (content != null) { PyType inside_type = context.getType(content); if (inside_type != null && !PyTypeChecker.isUnknown(inside_type)) { if (((PyStarArgument) arg).isKeyword()) { if (!PyABCUtil.isSubtype(inside_type, PyNames.MAPPING)) { holder.registerProblem( arg, PyBundle.message("INSP.expected.dict.got.$0", inside_type.getName())); } } else { // * arg if (!PyABCUtil.isSubtype(inside_type, PyNames.ITERABLE)) { holder.registerProblem( arg, PyBundle.message("INSP.expected.iter.got.$0", inside_type.getName())); } } } } } } }
@Nullable private static PyType derefType( @NotNull Ref<PyType> typeRef, @NotNull PyTypeProvider typeProvider) { final PyType type = typeRef.get(); if (type != null) { type.assertValid(typeProvider.toString()); } return type; }
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(text); } 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.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()); } final PyArgumentList argList = PsiTreeUtil.getParentOfType(expression, PyArgumentList.class); if (argList != null) { final CallArgumentsMapping result = argList.analyzeCall(PyResolveContext.noImplicits()); if (result.getMarkedCallee() != null) { final PyNamedParameter namedParameter = result.getPlainMappedParams().get(expression); if (namedParameter != null) { candidates.add(namedParameter.getName()); } } } return candidates; }
@NotNull private static List<RatedResolveResult> resolveMemberFromReferenceTypeProviders( @NotNull PsiElement parent, @NotNull String referencedName) { final PyResolveContext resolveContext = PyResolveContext.defaultContext(); final PyType refType = PyReferenceExpressionImpl.getReferenceTypeFromProviders( parent, resolveContext.getTypeEvalContext(), null); if (refType != null) { final List<? extends RatedResolveResult> result = refType.resolveMember(referencedName, null, AccessDirection.READ, resolveContext); if (result != null) { return Lists.newArrayList(result); } } return Collections.emptyList(); }
@Nullable @Override public PyType getCallType( @NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) { PyType type = null; for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) { type = typeProvider.getCallType(this, callSite, context); if (type != null) { type.assertValid(typeProvider.toString()); break; } } if (type == null) { type = context.getReturnType(this); } final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCallSite(callSite, context); if (results != null) { return analyzeCallType(type, results.getReceiver(), results.getArguments(), context); } return type; }
@Nullable @Override public PyType getCallType( @NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) { for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) { final PyType type = typeProvider.getCallType(this, callSite, context); if (type != null) { type.assertValid(typeProvider.toString()); return type; } } final PyExpression receiver = PyTypeChecker.getReceiver(callSite, this); final List<PyExpression> arguments = PyTypeChecker.getArguments(callSite, this); final List<PyParameter> parameters = PyUtil.getParameters(this, context); final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context); final List<PyParameter> explicitParameters = PyTypeChecker.filterExplicitParameters(parameters, this, callSite, resolveContext); final Map<PyExpression, PyNamedParameter> mapping = PyCallExpressionHelper.mapArguments(arguments, explicitParameters); return getCallType(receiver, mapping, context); }
private static boolean isAbstract(@NotNull PyClass pyClass) { final PyType metaClass = pyClass.getMetaClassType( TypeEvalContext.userInitiated(pyClass.getProject(), pyClass.getContainingFile())); if (metaClass instanceof PyClassLikeType && PyNames.ABC_META_CLASS.equals(metaClass.getName())) { return true; } if (metaClass == null) { final PyExpression metaClassExpr = as(pyClass.getMetaClassExpression(), PyReferenceExpression.class); if (metaClassExpr != null && PyNames.ABC_META_CLASS.equals(metaClassExpr.getName())) { return true; } } for (PyFunction method : pyClass.getMethods(false)) { if (PyUtil.isDecoratedAsAbstract(method)) { return true; } } return false; }