Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add an option to include rustdoc in ABI #876

Merged
merged 5 commits into from
Aug 4, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/abi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ edition = "2021"
crate-type = ["cdylib"]

[dependencies]
near-sdk = { path = "../../near-sdk", features = ["abi"] }
# "abi-doc" is an optional feature that includes contract functions' rustdocs into the ABI file
near-sdk = { path = "../../near-sdk", features = ["abi", "abi-doc"] }
serde = { version = "1", features = ["derive"] }
schemars = "0.8"

Expand Down
1 change: 1 addition & 0 deletions examples/abi/res/abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"functions": [
{
"name": "add",
"doc": " Adds two pairs point-wise.",
"is_view": true,
"params": [
{
Expand Down
Binary file modified examples/abi/res/abi.wasm
Binary file not shown.
1 change: 1 addition & 0 deletions examples/abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub struct Adder {}

#[near_bindgen]
impl Adder {
/// Adds two pairs point-wise.
pub fn add(&self, a: Pair, b: Pair) -> Pair {
sum_pair(&a, &b)
}
Expand Down
1 change: 1 addition & 0 deletions near-sdk-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ Inflector = { version = "0.11.4", default-features = false, features = [] }

[features]
abi = []
abi-doc = ["abi"]
9 changes: 9 additions & 0 deletions near-sdk-macros/src/core_impl/abi/abi_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ impl ImplItemMethodInfo {
/// If args are serialized with Borsh it will not include `#[derive(borsh::BorshSchema)]`.
pub fn abi_struct(&self) -> TokenStream2 {
let function_name_str = self.attr_signature_info.ident.to_string();
#[cfg(feature = "abi-doc")]
let function_doc =
match super::doc::parse_rustdoc(&self.attr_signature_info.non_bindgen_attrs) {
Some(doc) => quote! { Some(#doc.to_string()) },
None => quote! { None },
};
#[cfg(not(feature = "abi-doc"))]
let function_doc = quote! { None };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm skeptical this should be a feature at all. This wouldn't be compiled to wasm32 so only really comes at the cost of trivial compile time for native targets. Feels a little unwieldy to enforce specific feature usage to enable rather than something that can be enabled/disabled when the ABI is generated (cargo-near). WDYT? Feels like there is a use case where someone might want to output docs and not output docs for two different outputs for different use cases

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. Post-processing this makes more sense and even allows us to remove schemars generated doc strings. You can try this cargo-near branch in conjunction with this PR: https://github.com/near/cargo-near/tree/daniyar/rustdoc.

let is_view = matches!(&self.attr_signature_info.method_type, &MethodType::View);
let is_init = matches!(
&self.attr_signature_info.method_type,
Expand Down Expand Up @@ -153,6 +161,7 @@ impl ImplItemMethodInfo {
quote! {
near_sdk::__private::AbiFunction {
name: #function_name_str.to_string(),
doc: #function_doc,
is_view: #is_view,
is_init: #is_init,
is_payable: #is_payable,
Expand Down
25 changes: 25 additions & 0 deletions near-sdk-macros/src/core_impl/abi/doc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use syn::{Attribute, Lit::Str, Meta::NameValue, MetaNameValue};

pub fn parse_rustdoc(attrs: &[Attribute]) -> Option<String> {
let doc = attrs
.iter()
.filter_map(|attr| {
if attr.path.is_ident("doc") {
if let NameValue(MetaNameValue { lit: Str(s), .. }) = attr.parse_meta().ok()? {
Some(s.value())
} else {
None
}
} else {
None
}
})
.collect::<Vec<_>>()
.join("\n");

if doc.is_empty() {
None
} else {
Some(doc)
}
}
2 changes: 2 additions & 0 deletions near-sdk-macros/src/core_impl/abi/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
pub mod abi_generator;
pub mod abi_visitor;
#[cfg(feature = "abi-doc")]
mod doc;
1 change: 1 addition & 0 deletions near-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ default = ["wee_alloc", "unit-testing"]
expensive-debug = []
unstable = ["once_cell"]
abi = ["schemars", "near-sdk-macros/abi"]
abi-doc = ["abi", "near-sdk-macros/abi-doc"]
unit-testing = ["near-vm-logic", "near-primitives-core", "near-primitives", "near-crypto"]

[package.metadata.docs.rs]
Expand Down
3 changes: 3 additions & 0 deletions near-sdk/src/private/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ impl Abi {
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
pub struct AbiFunction {
pub name: String,
/// Human-readable documentation parsed from the source file.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub doc: Option<String>,
/// Whether function does not modify the state.
#[serde(default, skip_serializing_if = "is_false")]
pub is_view: bool,
Expand Down