зеркало из https://github.com/mozilla/uniffi-rs.git
Docstrings for proc macros (#1862)
* test: add docstring tests for proc-macros * feat: support docstrings in metadata * fix(bindgen): improve docstrings in Enums and Errors * chore: add .idea to .gitignore * chore: add changelog entry
This commit is contained in:
Родитель
a93bdfa249
Коммит
45d0f340f7
|
@ -2,6 +2,7 @@ target
|
|||
.*.swp
|
||||
*.jar
|
||||
.vscode
|
||||
.idea
|
||||
xcuserdata
|
||||
docs/manual/src/internals/api
|
||||
examples/app/ios/Generated
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
[the external types docs](https://mozilla.github.io/uniffi-rs/udl/ext_types.html)
|
||||
- Add support for [docstrings in UDL](https://mozilla.github.io/uniffi-rs/udl/docstrings.html)
|
||||
- Ability for UDL to use external trait interfaces [#1831](https://github.com/mozilla/uniffi-rs/issues/1831)
|
||||
- Add support for docstrings via procmacros [#1862](https://github.com/mozilla/uniffi-rs/pull/1862)
|
||||
|
||||
[All changes in [[UnreleasedUniFFIVersion]]](https://github.com/mozilla/uniffi-rs/compare/v0.25.2...HEAD).
|
||||
|
||||
|
|
|
@ -1725,6 +1725,17 @@ dependencies = [
|
|||
"uniffi_testing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi-fixture-docstring-proc-macro"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"thiserror",
|
||||
"uniffi",
|
||||
"uniffi_bindgen",
|
||||
"uniffi_testing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi-fixture-ext-types"
|
||||
version = "0.22.0"
|
||||
|
|
|
@ -34,6 +34,7 @@ members = [
|
|||
"fixtures/ext-types/sub-lib",
|
||||
|
||||
"fixtures/docstring",
|
||||
"fixtures/docstring-proc-macro",
|
||||
"fixtures/foreign-executor",
|
||||
"fixtures/keywords/kotlin",
|
||||
"fixtures/keywords/rust",
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
[package]
|
||||
name = "uniffi-fixture-docstring-proc-macro"
|
||||
version = "0.22.0"
|
||||
authors = ["Firefox Sync Team <sync-team@mozilla.com>"]
|
||||
edition = "2021"
|
||||
license = "MPL-2.0"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
name = "uniffi_fixture_docstring_proc_macro"
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
||||
[dependencies]
|
||||
thiserror = "1.0"
|
||||
uniffi = { path = "../../uniffi" }
|
||||
|
||||
[build-dependencies]
|
||||
uniffi = { path = "../../uniffi", features = ["build"] }
|
||||
|
||||
[dev-dependencies]
|
||||
glob = "0.3"
|
||||
uniffi = { path = "../../uniffi", features = ["bindgen-tests"] }
|
||||
uniffi_bindgen = { path = "../../uniffi_bindgen" }
|
||||
uniffi_testing = { path = "../../uniffi_testing" }
|
|
@ -0,0 +1,3 @@
|
|||
# A basic test for uniffi components
|
||||
|
||||
This test covers docstrings in proc-macro mode.
|
|
@ -0,0 +1,7 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
fn main() {
|
||||
uniffi::generate_scaffolding("./src/docstring-proc-macro.udl").unwrap();
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
/// <docstring-namespace>
|
||||
namespace uniffi_docstring_proc_macro {};
|
|
@ -0,0 +1,97 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
/// <docstring-enum>
|
||||
#[derive(uniffi::Enum)]
|
||||
enum EnumTest {
|
||||
/// <docstring-enum-variant>
|
||||
One,
|
||||
/// <docstring-enum-variant-2>
|
||||
Two,
|
||||
}
|
||||
|
||||
/// <docstring-associated-enum>
|
||||
#[derive(uniffi::Enum)]
|
||||
pub enum AssociatedEnumTest {
|
||||
/// <docstring-associated-enum-variant>
|
||||
Test {
|
||||
/// <docstring-variant-field>
|
||||
code: i16,
|
||||
},
|
||||
/// <docstring-associated-enum-variant-2>
|
||||
Test2 { code: i16 },
|
||||
}
|
||||
|
||||
/// <docstring-error>
|
||||
#[derive(uniffi::Error, Debug, thiserror::Error)]
|
||||
#[uniffi(flat_error)]
|
||||
enum ErrorTest {
|
||||
/// <docstring-error-variant>
|
||||
#[error("Test")]
|
||||
One,
|
||||
/// <docstring-error-variant-2>
|
||||
#[error("Two")]
|
||||
Two,
|
||||
}
|
||||
|
||||
/// <docstring-associated-error>
|
||||
#[derive(uniffi::Error, Debug, thiserror::Error)]
|
||||
enum AssociatedErrorTest {
|
||||
/// <docstring-associated-error-variant>
|
||||
#[error("Test")]
|
||||
Test { code: i16 },
|
||||
/// <docstring-associated-error-variant-2>
|
||||
#[error("Test2")]
|
||||
Test2 { code: i16 },
|
||||
}
|
||||
|
||||
/// <docstring-object>
|
||||
#[derive(uniffi::Object)]
|
||||
pub struct ObjectTest {}
|
||||
|
||||
#[uniffi::export]
|
||||
impl ObjectTest {
|
||||
/// <docstring-primary-constructor>
|
||||
#[uniffi::constructor]
|
||||
pub fn new() -> Arc<Self> {
|
||||
Arc::new(ObjectTest {})
|
||||
}
|
||||
|
||||
/// <docstring-alternate-constructor>
|
||||
#[uniffi::constructor]
|
||||
pub fn new_alternate() -> Arc<Self> {
|
||||
Arc::new(ObjectTest {})
|
||||
}
|
||||
|
||||
/// <docstring-method>
|
||||
pub fn test(&self) {}
|
||||
}
|
||||
|
||||
/// <docstring-record>
|
||||
#[derive(uniffi::Record)]
|
||||
struct RecordTest {
|
||||
/// <docstring-record-field>
|
||||
test: i32,
|
||||
}
|
||||
|
||||
/// <docstring-function>
|
||||
#[uniffi::export]
|
||||
pub fn test() {
|
||||
let _ = ErrorTest::One;
|
||||
let _ = ErrorTest::Two;
|
||||
}
|
||||
|
||||
#[uniffi::export]
|
||||
pub fn test_without_docstring() {}
|
||||
|
||||
/// <docstring-callback>
|
||||
#[uniffi::export(callback_interface)]
|
||||
pub trait CallbackTest {
|
||||
/// <docstring-callback-method>
|
||||
fn test(&self);
|
||||
}
|
||||
|
||||
uniffi::include_scaffolding!("docstring-proc-macro");
|
|
@ -0,0 +1,35 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This test ensures the generated code works as expected when documentation comments are generated.
|
||||
// Note: we do not check for existence of the doc comments here, as they are not programmatically
|
||||
// exposed to the code.
|
||||
// https://github.com/mozilla/uniffi-rs/pull/1493#discussion_r1375337478
|
||||
|
||||
import uniffi.fixture.docstring.proc.macro.*;
|
||||
|
||||
test()
|
||||
|
||||
EnumTest.ONE
|
||||
EnumTest.TWO
|
||||
|
||||
AssociatedEnumTest.Test(0)
|
||||
AssociatedEnumTest.Test2(0)
|
||||
|
||||
ErrorTest.One("hello")
|
||||
ErrorTest.Two("hello")
|
||||
|
||||
AssociatedErrorTest.Test(0)
|
||||
AssociatedErrorTest.Test2(0)
|
||||
|
||||
val obj1 = ObjectTest
|
||||
val obj2 = ObjectTest.newAlternate()
|
||||
obj2.test()
|
||||
|
||||
val rec = RecordTest(123)
|
||||
val recField = rec.test
|
||||
|
||||
class CallbackImpls() : CallbackTest {
|
||||
override fun test() {}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# Test namespace
|
||||
import uniffi_docstring_proc_macro
|
||||
assert uniffi_docstring_proc_macro.__doc__
|
||||
|
||||
from uniffi_docstring_proc_macro import *
|
||||
|
||||
# Test function
|
||||
assert test.__doc__ == "<docstring-function>"
|
||||
assert test_without_docstring.__doc__ is None
|
||||
|
||||
# Test enums
|
||||
assert EnumTest.__doc__ == "<docstring-enum>"
|
||||
|
||||
# Simple enum variants can't be tested, because `__doc__` is not supported for enums
|
||||
# assert EnumTest.ONE.__doc__ == "<docstring-enum-variant>"
|
||||
# assert EnumTest.TWO.__doc__ == "<docstring-enum-variant-2>"
|
||||
|
||||
assert AssociatedEnumTest.__doc__ == "<docstring-associated-enum>"
|
||||
|
||||
# `__doc__` is lost because of how enum templates are generated
|
||||
# https://github.com/mozilla/uniffi-rs/blob/eb97592f8c48a7f5cf02a94662b8b7861a6544f3/uniffi_bindgen/src/bindings/python/templates/EnumTemplate.py#L60
|
||||
# assert AssociatedEnumTest.TEST.__doc__ == "<docstring-associated-enum-variant>"
|
||||
# assert AssociatedEnumTest.TEST2.__doc__ == "<docstring-associated-enum-variant-2>"
|
||||
|
||||
# Test errors
|
||||
assert ErrorTest.__doc__ == "<docstring-error>"
|
||||
assert ErrorTest.One.__doc__ == "<docstring-error-variant>"
|
||||
assert ErrorTest.Two.__doc__ == "<docstring-error-variant-2>"
|
||||
|
||||
assert AssociatedErrorTest.__doc__ == "<docstring-associated-error>"
|
||||
assert AssociatedErrorTest.Test.__doc__ == "<docstring-associated-error-variant>"
|
||||
assert AssociatedErrorTest.Test2.__doc__ == "<docstring-associated-error-variant-2>"
|
||||
|
||||
# Test objects
|
||||
assert ObjectTest.__doc__ == "<docstring-object>"
|
||||
assert ObjectTest.__init__.__doc__ == "<docstring-primary-constructor>"
|
||||
assert ObjectTest.new_alternate.__doc__ == "<docstring-alternate-constructor>"
|
||||
assert ObjectTest.test.__doc__ == "<docstring-method>"
|
||||
|
||||
# Test records
|
||||
assert RecordTest.__doc__ == "<docstring-record>"
|
||||
|
||||
# `__doc__` is not supported for class fields
|
||||
# assert RecordTest.test.__doc__ == "<docstring-record-field>"
|
||||
|
||||
# Test callbacks
|
||||
assert CallbackTest.__doc__ == "<docstring-callback>"
|
||||
assert CallbackTest.test.__doc__ == "<docstring-callback-method>"
|
|
@ -0,0 +1,36 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This test ensures the generated code works as expected when documentation comments are generated.
|
||||
// Note: we do not check for existence of the doc comments here, as they are not programmatically
|
||||
// exposed to the code.
|
||||
// https://github.com/mozilla/uniffi-rs/pull/1493#discussion_r1375337478
|
||||
|
||||
import uniffi_docstring_proc_macro
|
||||
|
||||
test()
|
||||
|
||||
var _ = EnumTest.one
|
||||
var _ = EnumTest.two
|
||||
|
||||
var _ = AssociatedEnumTest.test(code: 0)
|
||||
var _ = AssociatedEnumTest.test2(code: 0)
|
||||
|
||||
var _ = ErrorTest.One(message: "hello")
|
||||
var _ = ErrorTest.Two(message: "hello")
|
||||
|
||||
var _ = AssociatedErrorTest.Test(code: 0)
|
||||
var _ = AssociatedErrorTest.Test2(code: 0)
|
||||
|
||||
var obj1 = ObjectTest()
|
||||
var obj2 = ObjectTest.newAlternate()
|
||||
obj2.test()
|
||||
|
||||
var rec = RecordTest(test: 123)
|
||||
var recField = rec.test
|
||||
|
||||
class CallbackImpls: CallbackTest {
|
||||
func test() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
uniffi::build_foreign_language_testcases!(
|
||||
"tests/bindings/test_docstring.kts",
|
||||
"tests/bindings/test_docstring.swift",
|
||||
"tests/bindings/test_docstring.py",
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use uniffi_bindgen::bindings::TargetLanguage;
|
||||
use uniffi_testing::UniFFITestHelper;
|
||||
|
||||
const DOCSTRINGS: &[&str] = &[
|
||||
"<docstring-alternate-constructor>",
|
||||
"<docstring-associated-enum-variant-2>",
|
||||
"<docstring-associated-enum-variant>",
|
||||
"<docstring-associated-enum>",
|
||||
"<docstring-associated-error-variant-2>",
|
||||
"<docstring-associated-error-variant>",
|
||||
"<docstring-associated-error>",
|
||||
"<docstring-callback-method>",
|
||||
"<docstring-callback>",
|
||||
"<docstring-enum-variant-2>",
|
||||
"<docstring-enum-variant>",
|
||||
"<docstring-enum>",
|
||||
"<docstring-error-variant-2>",
|
||||
"<docstring-error-variant>",
|
||||
"<docstring-error>",
|
||||
"<docstring-function>",
|
||||
"<docstring-method>",
|
||||
"<docstring-namespace>",
|
||||
"<docstring-object>",
|
||||
"<docstring-primary-constructor>",
|
||||
"<docstring-record-field>",
|
||||
"<docstring-record>",
|
||||
"<docstring-variant-field>",
|
||||
];
|
||||
|
||||
fn test_docstring(language: TargetLanguage, file_extension: &str) {
|
||||
let test_helper = UniFFITestHelper::new(std::env!("CARGO_PKG_NAME")).unwrap();
|
||||
|
||||
let out_dir = test_helper
|
||||
.create_out_dir(
|
||||
std::env!("CARGO_TARGET_TMPDIR"),
|
||||
format!("test-docstring-proc-macro-{}", language),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let cdylib_path = test_helper.copy_cdylib_to_out_dir(&out_dir).unwrap();
|
||||
|
||||
uniffi_bindgen::library_mode::generate_bindings(
|
||||
&cdylib_path,
|
||||
None,
|
||||
&[language],
|
||||
None,
|
||||
&out_dir,
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let glob_pattern = out_dir.join(format!("**/*.{}", file_extension));
|
||||
|
||||
let sources = glob::glob(glob_pattern.as_str())
|
||||
.unwrap()
|
||||
.flatten()
|
||||
.map(|p| String::from(p.to_string_lossy()))
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
assert_eq!(sources.len(), 1);
|
||||
|
||||
let bindings_source = std::fs::read_to_string(&sources[0]).unwrap();
|
||||
|
||||
let expected: Vec<String> = vec![];
|
||||
assert_eq!(
|
||||
expected,
|
||||
DOCSTRINGS
|
||||
.iter()
|
||||
.filter(|v| !bindings_source.contains(*v))
|
||||
.map(|v| v.to_string())
|
||||
.collect::<Vec::<_>>(),
|
||||
"docstrings not found in {}",
|
||||
&sources[0]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_docstring_kotlin() {
|
||||
test_docstring(TargetLanguage::Kotlin, "kt");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_docstring_python() {
|
||||
test_docstring(TargetLanguage::Python, "py");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_docstring_swift() {
|
||||
test_docstring(TargetLanguage::Swift, "swift");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
[bindings.kotlin]
|
||||
package_name = "uniffi.fixture.docstring.proc.macro"
|
||||
cdylib_name = "uniffi_fixture_docstring_proc_macro"
|
||||
|
||||
[bindings.python]
|
||||
cdylib_name = "uniffi_fixture_docstring_proc_macro"
|
||||
|
||||
[bindings.swift]
|
||||
cdylib_name = "uniffi_fixture_docstring_proc_macro"
|
|
@ -41,6 +41,7 @@ sealed class {{ type_name }}{% if contains_object_references %}: Disposable {% e
|
|||
{% else -%}
|
||||
data class {{ variant|type_name(ci) }}(
|
||||
{% for field in variant.fields() -%}
|
||||
{%- call kt::docstring(field, 8) %}
|
||||
val {{ field.name()|var_name }}: {{ field|type_name(ci) }}{% if loop.last %}{% else %}, {% endif %}
|
||||
{% endfor -%}
|
||||
) : {{ type_name }}() {
|
||||
|
|
|
@ -22,6 +22,7 @@ sealed class {{ type_name }}: Exception(){% if contains_object_references %}, Di
|
|||
{%- let variant_name = variant|error_variant_name %}
|
||||
class {{ variant_name }}(
|
||||
{% for field in variant.fields() -%}
|
||||
{%- call kt::docstring(field, 8) %}
|
||||
val {{ field.name()|var_name }}: {{ field|type_name(ci) }}{% if loop.last %}{% else %}, {% endif %}
|
||||
{% endfor -%}
|
||||
) : {{ type_name }}() {
|
||||
|
|
|
@ -25,7 +25,8 @@ class {{ type_name }}:
|
|||
{%- call py::docstring(variant, 8) %}
|
||||
|
||||
{%- for field in variant.fields() %}
|
||||
{{ field.name()|var_name }}: "{{ field|type_name }}";
|
||||
{{ field.name()|var_name }}: "{{ field|type_name }}"
|
||||
{%- call py::docstring(field, 8) %}
|
||||
{%- endfor %}
|
||||
|
||||
@typing.no_type_check
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
public enum {{ type_name }} {
|
||||
{% for variant in e.variants() %}
|
||||
{%- call swift::docstring(variant, 4) %}
|
||||
case {{ variant.name()|enum_variant_swift_quoted }}{% if variant.fields().len() > 0 %}({% call swift::field_list_decl(variant) %}){% endif -%}
|
||||
case {{ variant.name()|enum_variant_swift_quoted }}{% if variant.fields().len() > 0 %}(
|
||||
{%- call swift::field_list_decl(variant) %}
|
||||
){% endif -%}
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,9 @@ public enum {{ type_name }} {
|
|||
{%- else %}
|
||||
{% for variant in e.variants() %}
|
||||
{%- call swift::docstring(variant, 4) %}
|
||||
case {{ variant.name()|class_name }}{% if variant.fields().len() > 0 %}({% call swift::field_list_decl(variant) %}){% endif -%}
|
||||
case {{ variant.name()|class_name }}{% if variant.fields().len() > 0 %}(
|
||||
{%- call swift::field_list_decl(variant) %}
|
||||
){% endif -%}
|
||||
{% endfor %}
|
||||
|
||||
{%- endif %}
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
-#}
|
||||
{% macro field_list_decl(item) %}
|
||||
{%- for field in item.fields() -%}
|
||||
{%- call docstring(field, 8) %}
|
||||
{{ field.name()|var_name }}: {{ field|type_name -}}
|
||||
{%- match field.default_value() %}
|
||||
{%- when Some with(literal) %} = {{ literal|literal_swift(field) }}
|
||||
|
|
|
@ -3,8 +3,8 @@ use quote::quote;
|
|||
use syn::{Data, DataEnum, DeriveInput, Field, Index};
|
||||
|
||||
use crate::util::{
|
||||
create_metadata_items, derive_all_ffi_traits, ident_to_string, mod_path, tagged_impl_header,
|
||||
try_metadata_value_from_usize, try_read_field,
|
||||
create_metadata_items, derive_all_ffi_traits, extract_docstring, ident_to_string, mod_path,
|
||||
tagged_impl_header, try_metadata_value_from_usize, try_read_field,
|
||||
};
|
||||
|
||||
pub fn expand_enum(input: DeriveInput, udl_mode: bool) -> syn::Result<TokenStream> {
|
||||
|
@ -18,10 +18,12 @@ pub fn expand_enum(input: DeriveInput, udl_mode: bool) -> syn::Result<TokenStrea
|
|||
}
|
||||
};
|
||||
let ident = &input.ident;
|
||||
let docstring = extract_docstring(&input.attrs)?;
|
||||
let ffi_converter_impl = enum_ffi_converter_impl(ident, &enum_, udl_mode);
|
||||
|
||||
let meta_static_var = (!udl_mode).then(|| {
|
||||
enum_meta_static_var(ident, &enum_).unwrap_or_else(syn::Error::into_compile_error)
|
||||
enum_meta_static_var(ident, docstring, &enum_)
|
||||
.unwrap_or_else(syn::Error::into_compile_error)
|
||||
});
|
||||
|
||||
Ok(quote! {
|
||||
|
@ -136,7 +138,11 @@ fn write_field(f: &Field) -> TokenStream {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn enum_meta_static_var(ident: &Ident, enum_: &DataEnum) -> syn::Result<TokenStream> {
|
||||
pub(crate) fn enum_meta_static_var(
|
||||
ident: &Ident,
|
||||
docstring: String,
|
||||
enum_: &DataEnum,
|
||||
) -> syn::Result<TokenStream> {
|
||||
let name = ident_to_string(ident);
|
||||
let module_path = mod_path()?;
|
||||
|
||||
|
@ -146,6 +152,7 @@ pub(crate) fn enum_meta_static_var(ident: &Ident, enum_: &DataEnum) -> syn::Resu
|
|||
.concat_str(#name)
|
||||
};
|
||||
metadata_expr.extend(variant_metadata(enum_)?);
|
||||
metadata_expr.extend(quote! { .concat_str(#docstring) });
|
||||
Ok(create_metadata_items("enum", &name, metadata_expr, None))
|
||||
}
|
||||
|
||||
|
@ -178,7 +185,13 @@ pub fn variant_metadata(enum_: &DataEnum) -> syn::Result<Vec<TokenStream>> {
|
|||
.collect::<syn::Result<Vec<_>>>()?;
|
||||
|
||||
let name = ident_to_string(&v.ident);
|
||||
let docstring = extract_docstring(&v.attrs)?;
|
||||
let field_types = v.fields.iter().map(|f| &f.ty);
|
||||
let field_docstrings = v.fields
|
||||
.iter()
|
||||
.map(|f| extract_docstring(&f.attrs))
|
||||
.collect::<syn::Result<Vec<_>>>()?;
|
||||
|
||||
Ok(quote! {
|
||||
.concat_str(#name)
|
||||
.concat_value(#fields_len)
|
||||
|
@ -187,7 +200,9 @@ pub fn variant_metadata(enum_: &DataEnum) -> syn::Result<Vec<TokenStream>> {
|
|||
.concat(<#field_types as ::uniffi::Lower<crate::UniFfiTag>>::TYPE_ID_META)
|
||||
// field defaults not yet supported for enums
|
||||
.concat_bool(false)
|
||||
.concat_str(#field_docstrings)
|
||||
)*
|
||||
.concat_str(#docstring)
|
||||
})
|
||||
})
|
||||
)
|
||||
|
|
|
@ -8,9 +8,9 @@ use syn::{
|
|||
use crate::{
|
||||
enum_::{rich_error_ffi_converter_impl, variant_metadata},
|
||||
util::{
|
||||
chain, create_metadata_items, derive_ffi_traits, either_attribute_arg, ident_to_string, kw,
|
||||
mod_path, parse_comma_separated, tagged_impl_header, try_metadata_value_from_usize,
|
||||
AttributeSliceExt, UniffiAttributeArgs,
|
||||
chain, create_metadata_items, derive_ffi_traits, either_attribute_arg, extract_docstring,
|
||||
ident_to_string, kw, mod_path, parse_comma_separated, tagged_impl_header,
|
||||
try_metadata_value_from_usize, AttributeSliceExt, UniffiAttributeArgs,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -30,13 +30,14 @@ pub fn expand_error(
|
|||
}
|
||||
};
|
||||
let ident = &input.ident;
|
||||
let docstring = extract_docstring(&input.attrs)?;
|
||||
let mut attr: ErrorAttr = input.attrs.parse_uniffi_attr_args()?;
|
||||
if let Some(attr_from_udl_mode) = attr_from_udl_mode {
|
||||
attr = attr.merge(attr_from_udl_mode)?;
|
||||
}
|
||||
let ffi_converter_impl = error_ffi_converter_impl(ident, &enum_, &attr, udl_mode);
|
||||
let meta_static_var = (!udl_mode).then(|| {
|
||||
error_meta_static_var(ident, &enum_, attr.flat.is_some())
|
||||
error_meta_static_var(ident, docstring, &enum_, attr.flat.is_some())
|
||||
.unwrap_or_else(syn::Error::into_compile_error)
|
||||
});
|
||||
|
||||
|
@ -192,6 +193,7 @@ fn flat_error_ffi_converter_impl(
|
|||
|
||||
pub(crate) fn error_meta_static_var(
|
||||
ident: &Ident,
|
||||
docstring: String,
|
||||
enum_: &DataEnum,
|
||||
flat: bool,
|
||||
) -> syn::Result<TokenStream> {
|
||||
|
@ -210,18 +212,23 @@ pub(crate) fn error_meta_static_var(
|
|||
} else {
|
||||
metadata_expr.extend(variant_metadata(enum_)?);
|
||||
}
|
||||
metadata_expr.extend(quote! { .concat_str(#docstring) });
|
||||
Ok(create_metadata_items("error", &name, metadata_expr, None))
|
||||
}
|
||||
|
||||
pub fn flat_error_variant_metadata(enum_: &DataEnum) -> syn::Result<Vec<TokenStream>> {
|
||||
let variants_len =
|
||||
try_metadata_value_from_usize(enum_.variants.len(), "UniFFI limits enums to 256 variants")?;
|
||||
Ok(std::iter::once(quote! { .concat_value(#variants_len) })
|
||||
std::iter::once(Ok(quote! { .concat_value(#variants_len) }))
|
||||
.chain(enum_.variants.iter().map(|v| {
|
||||
let name = ident_to_string(&v.ident);
|
||||
quote! { .concat_str(#name) }
|
||||
let docstring = extract_docstring(&v.attrs)?;
|
||||
Ok(quote! {
|
||||
.concat_str(#name)
|
||||
.concat_str(#docstring)
|
||||
})
|
||||
}))
|
||||
.collect())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
|
@ -68,18 +68,23 @@ pub(crate) fn expand_export(
|
|||
items,
|
||||
self_ident,
|
||||
callback_interface: false,
|
||||
} => trait_interface::gen_trait_scaffolding(&mod_path, args, self_ident, items, udl_mode),
|
||||
docstring,
|
||||
} => trait_interface::gen_trait_scaffolding(
|
||||
&mod_path, args, self_ident, items, udl_mode, docstring,
|
||||
),
|
||||
ExportItem::Trait {
|
||||
items,
|
||||
self_ident,
|
||||
callback_interface: true,
|
||||
docstring,
|
||||
} => {
|
||||
let trait_name = ident_to_string(&self_ident);
|
||||
let trait_impl_ident = callback_interface::trait_impl_ident(&trait_name);
|
||||
let trait_impl = callback_interface::trait_impl(&mod_path, &self_ident, &items)
|
||||
.unwrap_or_else(|e| e.into_compile_error());
|
||||
let metadata_items = callback_interface::metadata_items(&self_ident, &items, &mod_path)
|
||||
.unwrap_or_else(|e| vec![e.into_compile_error()]);
|
||||
let metadata_items =
|
||||
callback_interface::metadata_items(&self_ident, &items, &mod_path, docstring)
|
||||
.unwrap_or_else(|e| vec![e.into_compile_error()]);
|
||||
let ffi_converter_tokens =
|
||||
ffi_converter_callback_interface_impl(&self_ident, &trait_impl_ident, udl_mode);
|
||||
|
||||
|
|
|
@ -182,6 +182,7 @@ pub(super) fn metadata_items(
|
|||
self_ident: &Ident,
|
||||
items: &[ImplItem],
|
||||
module_path: &str,
|
||||
docstring: String,
|
||||
) -> syn::Result<Vec<TokenStream>> {
|
||||
let trait_name = ident_to_string(self_ident);
|
||||
let callback_interface_items = create_metadata_items(
|
||||
|
@ -191,6 +192,7 @@ pub(super) fn metadata_items(
|
|||
::uniffi::MetadataBuffer::from_code(::uniffi::metadata::codes::CALLBACK_INTERFACE)
|
||||
.concat_str(#module_path)
|
||||
.concat_str(#trait_name)
|
||||
.concat_str(#docstring)
|
||||
},
|
||||
None,
|
||||
);
|
||||
|
|
|
@ -7,6 +7,7 @@ use proc_macro2::{Ident, Span};
|
|||
use quote::ToTokens;
|
||||
|
||||
use super::attributes::{ExportAttributeArguments, ExportedImplFnAttributes};
|
||||
use crate::util::extract_docstring;
|
||||
use uniffi_meta::UniffiTraitDiscriminants;
|
||||
|
||||
pub(super) enum ExportItem {
|
||||
|
@ -21,6 +22,7 @@ pub(super) enum ExportItem {
|
|||
self_ident: Ident,
|
||||
items: Vec<ImplItem>,
|
||||
callback_interface: bool,
|
||||
docstring: String,
|
||||
},
|
||||
Struct {
|
||||
self_ident: Ident,
|
||||
|
@ -32,7 +34,8 @@ impl ExportItem {
|
|||
pub fn new(item: syn::Item, args: &ExportAttributeArguments) -> syn::Result<Self> {
|
||||
match item {
|
||||
syn::Item::Fn(item) => {
|
||||
let sig = FnSignature::new_function(item.sig)?;
|
||||
let docstring = extract_docstring(&item.attrs)?;
|
||||
let sig = FnSignature::new_function(item.sig, docstring)?;
|
||||
Ok(Self::Function { sig })
|
||||
}
|
||||
syn::Item::Impl(item) => Self::from_impl(item, args.constructor.is_some()),
|
||||
|
@ -88,14 +91,20 @@ impl ExportItem {
|
|||
}
|
||||
};
|
||||
|
||||
let docstring = extract_docstring(&impl_fn.attrs)?;
|
||||
let attrs = ExportedImplFnAttributes::new(&impl_fn.attrs)?;
|
||||
let item = if force_constructor || attrs.constructor {
|
||||
ImplItem::Constructor(FnSignature::new_constructor(
|
||||
self_ident.clone(),
|
||||
impl_fn.sig,
|
||||
docstring,
|
||||
)?)
|
||||
} else {
|
||||
ImplItem::Method(FnSignature::new_method(self_ident.clone(), impl_fn.sig)?)
|
||||
ImplItem::Method(FnSignature::new_method(
|
||||
self_ident.clone(),
|
||||
impl_fn.sig,
|
||||
docstring,
|
||||
)?)
|
||||
};
|
||||
|
||||
Ok(item)
|
||||
|
@ -117,6 +126,7 @@ impl ExportItem {
|
|||
}
|
||||
|
||||
let self_ident = item.ident.to_owned();
|
||||
let docstring = extract_docstring(&item.attrs)?;
|
||||
let items = item
|
||||
.items
|
||||
.into_iter()
|
||||
|
@ -132,6 +142,7 @@ impl ExportItem {
|
|||
}
|
||||
};
|
||||
|
||||
let docstring = extract_docstring(&tim.attrs)?;
|
||||
let attrs = ExportedImplFnAttributes::new(&tim.attrs)?;
|
||||
let item = if attrs.constructor {
|
||||
return Err(syn::Error::new_spanned(
|
||||
|
@ -143,6 +154,7 @@ impl ExportItem {
|
|||
self_ident.clone(),
|
||||
tim.sig,
|
||||
i as u32,
|
||||
docstring,
|
||||
)?)
|
||||
};
|
||||
|
||||
|
@ -154,6 +166,7 @@ impl ExportItem {
|
|||
items,
|
||||
self_ident,
|
||||
callback_interface,
|
||||
docstring,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ pub(super) fn gen_trait_scaffolding(
|
|||
self_ident: Ident,
|
||||
items: Vec<ImplItem>,
|
||||
udl_mode: bool,
|
||||
docstring: String,
|
||||
) -> syn::Result<TokenStream> {
|
||||
if let Some(rt) = args.async_runtime {
|
||||
return Err(syn::Error::new_spanned(rt, "not supported for traits"));
|
||||
|
@ -66,7 +67,7 @@ pub(super) fn gen_trait_scaffolding(
|
|||
.collect::<syn::Result<_>>()?;
|
||||
|
||||
let meta_static_var = (!udl_mode).then(|| {
|
||||
interface_meta_static_var(&self_ident, true, mod_path)
|
||||
interface_meta_static_var(&self_ident, true, mod_path, docstring)
|
||||
.unwrap_or_else(syn::Error::into_compile_error)
|
||||
});
|
||||
let ffi_converter_tokens = ffi_converter(mod_path, &self_ident, udl_mode);
|
||||
|
|
|
@ -8,6 +8,7 @@ use syn::ext::IdentExt;
|
|||
|
||||
use super::{attributes::ExportAttributeArguments, gen_ffi_function};
|
||||
use crate::fnsig::FnSignature;
|
||||
use crate::util::extract_docstring;
|
||||
use uniffi_meta::UniffiTraitDiscriminants;
|
||||
|
||||
pub(crate) fn expand_uniffi_trait_export(
|
||||
|
@ -157,12 +158,15 @@ fn process_uniffi_trait_method(
|
|||
unreachable!()
|
||||
};
|
||||
|
||||
let docstring = extract_docstring(&item.attrs)?;
|
||||
|
||||
let ffi_func = gen_ffi_function(
|
||||
&FnSignature::new_method(self_ident.clone(), item.sig.clone())?,
|
||||
&FnSignature::new_method(self_ident.clone(), item.sig.clone(), docstring.clone())?,
|
||||
&ExportAttributeArguments::default(),
|
||||
udl_mode,
|
||||
)?;
|
||||
// metadata for the method, which will be packed inside metadata for the trait.
|
||||
let method_meta = FnSignature::new_method(self_ident.clone(), item.sig)?.metadata_expr()?;
|
||||
let method_meta =
|
||||
FnSignature::new_method(self_ident.clone(), item.sig, docstring)?.metadata_expr()?;
|
||||
Ok((ffi_func, method_meta))
|
||||
}
|
||||
|
|
|
@ -23,30 +23,40 @@ pub(crate) struct FnSignature {
|
|||
// Only use this in UDL mode.
|
||||
// In general, it's not reliable because it fails for type aliases.
|
||||
pub looks_like_result: bool,
|
||||
pub docstring: String,
|
||||
}
|
||||
|
||||
impl FnSignature {
|
||||
pub(crate) fn new_function(sig: syn::Signature) -> syn::Result<Self> {
|
||||
Self::new(FnKind::Function, sig)
|
||||
pub(crate) fn new_function(sig: syn::Signature, docstring: String) -> syn::Result<Self> {
|
||||
Self::new(FnKind::Function, sig, docstring)
|
||||
}
|
||||
|
||||
pub(crate) fn new_method(self_ident: Ident, sig: syn::Signature) -> syn::Result<Self> {
|
||||
Self::new(FnKind::Method { self_ident }, sig)
|
||||
pub(crate) fn new_method(
|
||||
self_ident: Ident,
|
||||
sig: syn::Signature,
|
||||
docstring: String,
|
||||
) -> syn::Result<Self> {
|
||||
Self::new(FnKind::Method { self_ident }, sig, docstring)
|
||||
}
|
||||
|
||||
pub(crate) fn new_constructor(self_ident: Ident, sig: syn::Signature) -> syn::Result<Self> {
|
||||
Self::new(FnKind::Constructor { self_ident }, sig)
|
||||
pub(crate) fn new_constructor(
|
||||
self_ident: Ident,
|
||||
sig: syn::Signature,
|
||||
docstring: String,
|
||||
) -> syn::Result<Self> {
|
||||
Self::new(FnKind::Constructor { self_ident }, sig, docstring)
|
||||
}
|
||||
|
||||
pub(crate) fn new_trait_method(
|
||||
self_ident: Ident,
|
||||
sig: syn::Signature,
|
||||
index: u32,
|
||||
docstring: String,
|
||||
) -> syn::Result<Self> {
|
||||
Self::new(FnKind::TraitMethod { self_ident, index }, sig)
|
||||
Self::new(FnKind::TraitMethod { self_ident, index }, sig, docstring)
|
||||
}
|
||||
|
||||
pub(crate) fn new(kind: FnKind, sig: syn::Signature) -> syn::Result<Self> {
|
||||
pub(crate) fn new(kind: FnKind, sig: syn::Signature, docstring: String) -> syn::Result<Self> {
|
||||
let span = sig.span();
|
||||
let ident = sig.ident;
|
||||
let looks_like_result = looks_like_result(&sig.output);
|
||||
|
@ -97,6 +107,7 @@ impl FnSignature {
|
|||
args,
|
||||
return_ty: output,
|
||||
looks_like_result,
|
||||
docstring,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -193,6 +204,7 @@ impl FnSignature {
|
|||
return_ty,
|
||||
is_async,
|
||||
mod_path,
|
||||
docstring,
|
||||
..
|
||||
} = &self;
|
||||
let args_len = try_metadata_value_from_usize(
|
||||
|
@ -212,6 +224,7 @@ impl FnSignature {
|
|||
.concat_value(#args_len)
|
||||
#(#arg_metadata_calls)*
|
||||
.concat(<#return_ty as ::uniffi::LowerReturn<crate::UniFfiTag>>::TYPE_ID_META)
|
||||
.concat_str(#docstring)
|
||||
}),
|
||||
|
||||
FnKind::Method { self_ident } => {
|
||||
|
@ -225,6 +238,7 @@ impl FnSignature {
|
|||
.concat_value(#args_len)
|
||||
#(#arg_metadata_calls)*
|
||||
.concat(<#return_ty as ::uniffi::LowerReturn<crate::UniFfiTag>>::TYPE_ID_META)
|
||||
.concat_str(#docstring)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -240,6 +254,7 @@ impl FnSignature {
|
|||
.concat_value(#args_len)
|
||||
#(#arg_metadata_calls)*
|
||||
.concat(<#return_ty as ::uniffi::LowerReturn<crate::UniFfiTag>>::TYPE_ID_META)
|
||||
.concat_str(#docstring)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -253,6 +268,7 @@ impl FnSignature {
|
|||
.concat_value(#args_len)
|
||||
#(#arg_metadata_calls)*
|
||||
.concat(<#return_ty as ::uniffi::LowerReturn<crate::UniFfiTag>>::TYPE_ID_META)
|
||||
.concat_str(#docstring)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,15 +3,18 @@ use quote::quote;
|
|||
use syn::DeriveInput;
|
||||
use uniffi_meta::free_fn_symbol_name;
|
||||
|
||||
use crate::util::{create_metadata_items, ident_to_string, mod_path, tagged_impl_header};
|
||||
use crate::util::{
|
||||
create_metadata_items, extract_docstring, ident_to_string, mod_path, tagged_impl_header,
|
||||
};
|
||||
|
||||
pub fn expand_object(input: DeriveInput, udl_mode: bool) -> syn::Result<TokenStream> {
|
||||
let module_path = mod_path()?;
|
||||
let ident = &input.ident;
|
||||
let docstring = extract_docstring(&input.attrs)?;
|
||||
let name = ident_to_string(ident);
|
||||
let free_fn_ident = Ident::new(&free_fn_symbol_name(&module_path, &name), Span::call_site());
|
||||
let meta_static_var = (!udl_mode).then(|| {
|
||||
interface_meta_static_var(ident, false, &module_path)
|
||||
interface_meta_static_var(ident, false, &module_path, docstring)
|
||||
.unwrap_or_else(syn::Error::into_compile_error)
|
||||
});
|
||||
let interface_impl = interface_impl(ident, udl_mode);
|
||||
|
@ -131,16 +134,19 @@ pub(crate) fn interface_meta_static_var(
|
|||
ident: &Ident,
|
||||
is_trait: bool,
|
||||
module_path: &str,
|
||||
docstring: String,
|
||||
) -> syn::Result<TokenStream> {
|
||||
let name = ident_to_string(ident);
|
||||
|
||||
Ok(create_metadata_items(
|
||||
"interface",
|
||||
&name,
|
||||
quote! {
|
||||
::uniffi::MetadataBuffer::from_code(::uniffi::metadata::codes::INTERFACE)
|
||||
.concat_str(#module_path)
|
||||
.concat_str(#name)
|
||||
.concat_bool(#is_trait)
|
||||
::uniffi::MetadataBuffer::from_code(::uniffi::metadata::codes::INTERFACE)
|
||||
.concat_str(#module_path)
|
||||
.concat_str(#name)
|
||||
.concat_bool(#is_trait)
|
||||
.concat_str(#docstring)
|
||||
},
|
||||
None,
|
||||
))
|
||||
|
|
|
@ -6,9 +6,9 @@ use syn::{
|
|||
};
|
||||
|
||||
use crate::util::{
|
||||
create_metadata_items, derive_all_ffi_traits, either_attribute_arg, ident_to_string, kw,
|
||||
mod_path, tagged_impl_header, try_metadata_value_from_usize, try_read_field, AttributeSliceExt,
|
||||
UniffiAttributeArgs,
|
||||
create_metadata_items, derive_all_ffi_traits, either_attribute_arg, extract_docstring,
|
||||
ident_to_string, kw, mod_path, tagged_impl_header, try_metadata_value_from_usize,
|
||||
try_read_field, AttributeSliceExt, UniffiAttributeArgs,
|
||||
};
|
||||
|
||||
pub fn expand_record(input: DeriveInput, udl_mode: bool) -> syn::Result<TokenStream> {
|
||||
|
@ -23,10 +23,12 @@ pub fn expand_record(input: DeriveInput, udl_mode: bool) -> syn::Result<TokenStr
|
|||
};
|
||||
|
||||
let ident = &input.ident;
|
||||
let docstring = extract_docstring(&input.attrs)?;
|
||||
let ffi_converter = record_ffi_converter_impl(ident, &record, udl_mode)
|
||||
.unwrap_or_else(syn::Error::into_compile_error);
|
||||
let meta_static_var = (!udl_mode).then(|| {
|
||||
record_meta_static_var(ident, &record).unwrap_or_else(syn::Error::into_compile_error)
|
||||
record_meta_static_var(ident, docstring, &record)
|
||||
.unwrap_or_else(syn::Error::into_compile_error)
|
||||
});
|
||||
|
||||
Ok(quote! {
|
||||
|
@ -128,6 +130,7 @@ impl UniffiAttributeArgs for FieldAttributeArguments {
|
|||
|
||||
pub(crate) fn record_meta_static_var(
|
||||
ident: &Ident,
|
||||
docstring: String,
|
||||
record: &DataStruct,
|
||||
) -> syn::Result<TokenStream> {
|
||||
let name = ident_to_string(ident);
|
||||
|
@ -144,6 +147,7 @@ pub(crate) fn record_meta_static_var(
|
|||
.parse_uniffi_attr_args::<FieldAttributeArguments>()?;
|
||||
|
||||
let name = ident_to_string(f.ident.as_ref().unwrap());
|
||||
let docstring = extract_docstring(&f.attrs)?;
|
||||
let ty = &f.ty;
|
||||
let default = match attrs.default {
|
||||
Some(default) => {
|
||||
|
@ -162,6 +166,7 @@ pub(crate) fn record_meta_static_var(
|
|||
.concat_str(#name)
|
||||
.concat(<#ty as ::uniffi::Lower<crate::UniFfiTag>>::TYPE_ID_META)
|
||||
#default
|
||||
.concat_str(#docstring)
|
||||
})
|
||||
})
|
||||
.collect::<syn::Result<_>>()?;
|
||||
|
@ -175,6 +180,7 @@ pub(crate) fn record_meta_static_var(
|
|||
.concat_str(#name)
|
||||
.concat_value(#fields_len)
|
||||
#concat_fields
|
||||
.concat_str(#docstring)
|
||||
},
|
||||
None,
|
||||
))
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::path::{Path as StdPath, PathBuf};
|
|||
use syn::{
|
||||
ext::IdentExt,
|
||||
parse::{Parse, ParseStream},
|
||||
Attribute, Token,
|
||||
Attribute, Expr, Lit, Token,
|
||||
};
|
||||
|
||||
pub fn manifest_path() -> Result<PathBuf, String> {
|
||||
|
@ -276,3 +276,20 @@ impl Parse for ExternalTypeItem {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn extract_docstring(attrs: &[Attribute]) -> syn::Result<String> {
|
||||
return attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path().is_ident("doc"))
|
||||
.map(|attr| {
|
||||
let name_value = attr.meta.require_name_value()?;
|
||||
if let Expr::Lit(expr) = &name_value.value {
|
||||
if let Lit::Str(lit_str) = &expr.lit {
|
||||
return Ok(lit_str.value());
|
||||
}
|
||||
}
|
||||
Err(syn::Error::new_spanned(attr, "Cannot parse doc attribute"))
|
||||
})
|
||||
.collect::<syn::Result<Vec<_>>>()
|
||||
.map(|lines| lines.join("\n"));
|
||||
}
|
||||
|
|
|
@ -105,6 +105,10 @@ impl<'a> MetadataReader<'a> {
|
|||
String::from_utf8(slice.into()).context("Invalid string data")
|
||||
}
|
||||
|
||||
fn read_optional_string(&mut self) -> Result<Option<String>> {
|
||||
Ok(Some(self.read_string()?).filter(|str| !str.is_empty()))
|
||||
}
|
||||
|
||||
fn read_type(&mut self) -> Result<Type> {
|
||||
let value = self.read_u8()?;
|
||||
Ok(match value {
|
||||
|
@ -198,6 +202,7 @@ impl<'a> MetadataReader<'a> {
|
|||
let is_async = self.read_bool()?;
|
||||
let inputs = self.read_inputs()?;
|
||||
let (return_type, throws) = self.read_return_type()?;
|
||||
let docstring = self.read_optional_string()?;
|
||||
Ok(FnMetadata {
|
||||
module_path,
|
||||
name,
|
||||
|
@ -205,7 +210,7 @@ impl<'a> MetadataReader<'a> {
|
|||
inputs,
|
||||
return_type,
|
||||
throws,
|
||||
docstring: None,
|
||||
docstring,
|
||||
checksum: self.calc_checksum(),
|
||||
})
|
||||
}
|
||||
|
@ -216,6 +221,7 @@ impl<'a> MetadataReader<'a> {
|
|||
let name = self.read_string()?;
|
||||
let inputs = self.read_inputs()?;
|
||||
let (return_type, throws) = self.read_return_type()?;
|
||||
let docstring = self.read_optional_string()?;
|
||||
|
||||
return_type
|
||||
.filter(|t| {
|
||||
|
@ -233,7 +239,7 @@ impl<'a> MetadataReader<'a> {
|
|||
inputs,
|
||||
throws,
|
||||
checksum: self.calc_checksum(),
|
||||
docstring: None,
|
||||
docstring,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -244,6 +250,7 @@ impl<'a> MetadataReader<'a> {
|
|||
let is_async = self.read_bool()?;
|
||||
let inputs = self.read_inputs()?;
|
||||
let (return_type, throws) = self.read_return_type()?;
|
||||
let docstring = self.read_optional_string()?;
|
||||
Ok(MethodMetadata {
|
||||
module_path,
|
||||
self_name,
|
||||
|
@ -254,7 +261,7 @@ impl<'a> MetadataReader<'a> {
|
|||
throws,
|
||||
takes_self_by_arc: false, // not emitted by macros
|
||||
checksum: self.calc_checksum(),
|
||||
docstring: None,
|
||||
docstring,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -263,7 +270,7 @@ impl<'a> MetadataReader<'a> {
|
|||
module_path: self.read_string()?,
|
||||
name: self.read_string()?,
|
||||
fields: self.read_fields()?,
|
||||
docstring: None,
|
||||
docstring: self.read_optional_string()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -280,7 +287,7 @@ impl<'a> MetadataReader<'a> {
|
|||
module_path,
|
||||
name,
|
||||
variants,
|
||||
docstring: None,
|
||||
docstring: self.read_optional_string()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -295,7 +302,7 @@ impl<'a> MetadataReader<'a> {
|
|||
module_path: self.read_string()?,
|
||||
name: self.read_string()?,
|
||||
imp: ObjectImpl::from_is_trait(self.read_bool()?),
|
||||
docstring: None,
|
||||
docstring: self.read_optional_string()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -328,7 +335,7 @@ impl<'a> MetadataReader<'a> {
|
|||
Ok(CallbackInterfaceMetadata {
|
||||
module_path: self.read_string()?,
|
||||
name: self.read_string()?,
|
||||
docstring: None,
|
||||
docstring: self.read_optional_string()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -340,6 +347,7 @@ impl<'a> MetadataReader<'a> {
|
|||
let is_async = self.read_bool()?;
|
||||
let inputs = self.read_inputs()?;
|
||||
let (return_type, throws) = self.read_return_type()?;
|
||||
let docstring = self.read_optional_string()?;
|
||||
Ok(TraitMethodMetadata {
|
||||
module_path,
|
||||
trait_name,
|
||||
|
@ -351,7 +359,7 @@ impl<'a> MetadataReader<'a> {
|
|||
throws,
|
||||
takes_self_by_arc: false, // not emitted by macros
|
||||
checksum: self.calc_checksum(),
|
||||
docstring: None,
|
||||
docstring,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -366,7 +374,7 @@ impl<'a> MetadataReader<'a> {
|
|||
name,
|
||||
ty,
|
||||
default,
|
||||
docstring: None,
|
||||
docstring: self.read_optional_string()?,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
|
@ -379,7 +387,7 @@ impl<'a> MetadataReader<'a> {
|
|||
Ok(VariantMetadata {
|
||||
name: self.read_string()?,
|
||||
fields: self.read_fields()?,
|
||||
docstring: None,
|
||||
docstring: self.read_optional_string()?,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
|
@ -392,7 +400,7 @@ impl<'a> MetadataReader<'a> {
|
|||
Ok(VariantMetadata {
|
||||
name: self.read_string()?,
|
||||
fields: vec![],
|
||||
docstring: None,
|
||||
docstring: self.read_optional_string()?,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
|
|
Загрузка…
Ссылка в новой задаче