Example #1
0
 public PyProperty(PyMethod getter, PyMethod?setter)
 {
     Getter = getter;
     Setter = setter;
 }
Example #2
0
        static void Write(FileWriter writer, PyiDocGen docGen, IdentifierConverter idConverter, PyClass pyClass, PyMethod method, DocComments docComments, Dictionary <string, EnumType> toEnumType)
        {
            if (method.Attributes.Any(AttributeKind.ClassMethod))
            {
                writer.WriteLine("@classmethod");
            }
            if (method.Attributes.Any(AttributeKind.StaticMethod))
            {
                writer.WriteLine("@staticmethod");
            }
            bool isGetter = method.Attributes.Any(AttributeKind.Getter);
            bool isSetter = method.Attributes.Any(AttributeKind.Setter);

            if (isGetter)
            {
                writer.WriteLine("@property");
            }
            if (isSetter)
            {
                writer.WriteLine($"@{method.Name}.setter");
            }

            string sphinxReturnType = string.Empty;

            if (isGetter || isSetter)
            {
                if (docComments.Sections.FirstOrDefault() is not TextDocCommentSection textDocs || textDocs.Lines.Length == 0)
                {
                    throw new InvalidOperationException();
                }
                if (!ParseUtils.TryParseTypeAndDocs(textDocs.Lines[0], out _, out var typeInfo))
                {
                    throw new InvalidOperationException();
                }
                sphinxReturnType = typeInfo.SphinxType;
            }
            else
            {
                var returns = docComments.Sections.OfType <ReturnsDocCommentSection>().FirstOrDefault();
                if (returns is not null)
                {
                    sphinxReturnType = returns.Returns.SphinxType;
                }
            }

            bool isCtor = method.Attributes.Any(AttributeKind.New);

            writer.Write("def ");
            writer.Write(isCtor ? "__init__" : method.Name);
            writer.Write("(");
            int argCount = 0;

            if (isCtor)
            {
                writer.Write("self");
                argCount++;
            }
            var argsDocs = docComments.Sections.OfType <ArgsDocCommentSection>().FirstOrDefault();
            int hasThis  = method.Arguments.Count != 0 && method.Arguments[0].IsSelf ? 1 : 0;

            Dictionary <string, string> toDefaultValue;
            var argsAttr = method.Attributes.Attributes.FirstOrDefault(a => a.Kind == AttributeKind.Args);

            if (argsAttr is null)
            {
                toDefaultValue = new Dictionary <string, string>(StringComparer.Ordinal);
            }
            else
            {
                toDefaultValue = ParseUtils.GetArgsNameValues(argsAttr.Text).ToDictionary(a => a.name, a => a.value, StringComparer.Ordinal);
            }

            for (int i = 0; i < method.Arguments.Count; i++)
            {
                if (argsDocs is not null && argsDocs.Args.Length != method.Arguments.Count - hasThis)
                {
                    throw new InvalidOperationException();
                }
                var methodArg = method.Arguments[i];
                if (argCount > 0)
                {
                    writer.Write(", ");
                }
                argCount++;
                if (methodArg.IsSelf)
                {
                    writer.Write("self");
                }
                else
                {
                    writer.Write(methodArg.Name);

                    string docsSphinxType;
                    if (argsDocs is not null)
                    {
                        var docsArg = argsDocs.Args[i - hasThis];
                        if (docsArg.Name != methodArg.Name)
                        {
                            throw new InvalidOperationException();
                        }
                        docsSphinxType = docsArg.SphinxType;
                    }
                    else
                    {
                        docsSphinxType = string.Empty;
                    }
                    if (i == 1 && isSetter)
                    {
                        docsSphinxType = sphinxReturnType;
                    }

                    writer.Write(": ");
                    var type = GetType(pyClass, method.Name, methodArg.RustType, docsSphinxType);
                    writer.Write(type);

                    if (toDefaultValue.TryGetValue(methodArg.Name, out var defaultValueStr))
                    {
                        writer.Write(" = ");
                        if (!TryGetValueStr(idConverter, type, defaultValueStr, toEnumType, out var valueStr))
                        {
                            throw new InvalidOperationException($"method {pyClass.Name}.{method.Name}(): Couldn't convert default value `{defaultValueStr}` to a Python value");
                        }
                        writer.Write(valueStr);
                    }
                }
            }
            writer.Write(") -> ");
            if (method.HasReturnType && !isCtor)
            {
                writer.Write(GetReturnType(pyClass, method.Name, method.RustReturnType, sphinxReturnType));
            }
            else
            {
                writer.Write("None");
            }
            if (method.DocComments.Sections.Count == 0)
            {
                writer.WriteLine(": ...");
            }
            else
            {
                writer.WriteLine(":");
                using (writer.Indent()) {
                    WriteDocs(writer, docGen.Convert(method.DocComments));
                    writer.WriteLine("...");
                }
            }
        }