|
@@ -1,6 +1,6 @@
|
|
|
use crate::idl::*;
|
|
|
use crate::parser::context::CrateContext;
|
|
|
-use crate::parser::{self, accounts, error, program};
|
|
|
+use crate::parser::{self, accounts, docs, error, program};
|
|
|
use crate::Ty;
|
|
|
use crate::{AccountField, AccountsStruct, StateIx};
|
|
|
use anyhow::Result;
|
|
@@ -10,7 +10,7 @@ use std::collections::{HashMap, HashSet};
|
|
|
use std::path::Path;
|
|
|
|
|
|
const DERIVE_NAME: &str = "Accounts";
|
|
|
-// TODO: sharee this with `anchor_lang` crate.
|
|
|
+// TODO: share this with `anchor_lang` crate.
|
|
|
const ERROR_CODE_OFFSET: u32 = 6000;
|
|
|
|
|
|
// Parse an entire interface file.
|
|
@@ -18,6 +18,7 @@ pub fn parse(
|
|
|
filename: impl AsRef<Path>,
|
|
|
version: String,
|
|
|
seeds_feature: bool,
|
|
|
+ no_docs: bool,
|
|
|
safety_checks: bool,
|
|
|
) -> Result<Option<Idl>> {
|
|
|
let ctx = CrateContext::parse(filename)?;
|
|
@@ -29,7 +30,14 @@ pub fn parse(
|
|
|
None => return Ok(None),
|
|
|
Some(m) => m,
|
|
|
};
|
|
|
- let p = program::parse(program_mod)?;
|
|
|
+ let mut p = program::parse(program_mod)?;
|
|
|
+
|
|
|
+ if no_docs {
|
|
|
+ p.docs = None;
|
|
|
+ for ix in &mut p.ixs {
|
|
|
+ ix.docs = None;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
let accs = parse_account_derives(&ctx);
|
|
|
|
|
@@ -51,19 +59,31 @@ pub fn parse(
|
|
|
.map(|arg| {
|
|
|
let mut tts = proc_macro2::TokenStream::new();
|
|
|
arg.raw_arg.ty.to_tokens(&mut tts);
|
|
|
+ let doc = if !no_docs {
|
|
|
+ docs::parse(&arg.raw_arg.attrs)
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ };
|
|
|
let ty = tts.to_string().parse().unwrap();
|
|
|
IdlField {
|
|
|
name: arg.name.to_string().to_mixed_case(),
|
|
|
+ docs: doc,
|
|
|
ty,
|
|
|
}
|
|
|
})
|
|
|
.collect::<Vec<_>>();
|
|
|
let accounts_strct =
|
|
|
accs.get(&method.anchor_ident.to_string()).unwrap();
|
|
|
- let accounts =
|
|
|
- idl_accounts(&ctx, accounts_strct, &accs, seeds_feature);
|
|
|
+ let accounts = idl_accounts(
|
|
|
+ &ctx,
|
|
|
+ accounts_strct,
|
|
|
+ &accs,
|
|
|
+ seeds_feature,
|
|
|
+ no_docs,
|
|
|
+ );
|
|
|
IdlInstruction {
|
|
|
name,
|
|
|
+ docs: None,
|
|
|
accounts,
|
|
|
args,
|
|
|
returns: None,
|
|
@@ -91,9 +111,15 @@ pub fn parse(
|
|
|
syn::FnArg::Typed(arg_typed) => {
|
|
|
let mut tts = proc_macro2::TokenStream::new();
|
|
|
arg_typed.ty.to_tokens(&mut tts);
|
|
|
+ let doc = if !no_docs {
|
|
|
+ docs::parse(&arg_typed.attrs)
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ };
|
|
|
let ty = tts.to_string().parse().unwrap();
|
|
|
IdlField {
|
|
|
name: parser::tts_to_string(&arg_typed.pat).to_mixed_case(),
|
|
|
+ docs: doc,
|
|
|
ty,
|
|
|
}
|
|
|
}
|
|
@@ -101,9 +127,11 @@ pub fn parse(
|
|
|
})
|
|
|
.collect();
|
|
|
let accounts_strct = accs.get(&anchor_ident.to_string()).unwrap();
|
|
|
- let accounts = idl_accounts(&ctx, accounts_strct, &accs, seeds_feature);
|
|
|
+ let accounts =
|
|
|
+ idl_accounts(&ctx, accounts_strct, &accs, seeds_feature, no_docs);
|
|
|
IdlInstruction {
|
|
|
name,
|
|
|
+ docs: None,
|
|
|
accounts,
|
|
|
args,
|
|
|
returns: None,
|
|
@@ -120,9 +148,15 @@ pub fn parse(
|
|
|
.map(|f: &syn::Field| {
|
|
|
let mut tts = proc_macro2::TokenStream::new();
|
|
|
f.ty.to_tokens(&mut tts);
|
|
|
+ let doc = if !no_docs {
|
|
|
+ docs::parse(&f.attrs)
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ };
|
|
|
let ty = tts.to_string().parse().unwrap();
|
|
|
IdlField {
|
|
|
name: f.ident.as_ref().unwrap().to_string().to_mixed_case(),
|
|
|
+ docs: doc,
|
|
|
ty,
|
|
|
}
|
|
|
})
|
|
@@ -131,6 +165,7 @@ pub fn parse(
|
|
|
};
|
|
|
IdlTypeDefinition {
|
|
|
name: state.name,
|
|
|
+ docs: None,
|
|
|
ty: IdlTypeDefinitionTy::Struct { fields },
|
|
|
}
|
|
|
};
|
|
@@ -158,14 +193,22 @@ pub fn parse(
|
|
|
let args = ix
|
|
|
.args
|
|
|
.iter()
|
|
|
- .map(|arg| IdlField {
|
|
|
- name: arg.name.to_string().to_mixed_case(),
|
|
|
- ty: to_idl_type(&ctx, &arg.raw_arg.ty),
|
|
|
+ .map(|arg| {
|
|
|
+ let doc = if !no_docs {
|
|
|
+ docs::parse(&arg.raw_arg.attrs)
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ };
|
|
|
+ IdlField {
|
|
|
+ name: arg.name.to_string().to_mixed_case(),
|
|
|
+ docs: doc,
|
|
|
+ ty: to_idl_type(&ctx, &arg.raw_arg.ty),
|
|
|
+ }
|
|
|
})
|
|
|
.collect::<Vec<_>>();
|
|
|
// todo: don't unwrap
|
|
|
let accounts_strct = accs.get(&ix.anchor_ident.to_string()).unwrap();
|
|
|
- let accounts = idl_accounts(&ctx, accounts_strct, &accs, seeds_feature);
|
|
|
+ let accounts = idl_accounts(&ctx, accounts_strct, &accs, seeds_feature, no_docs);
|
|
|
let ret_type_str = ix.returns.ty.to_token_stream().to_string();
|
|
|
let returns = match ret_type_str.as_str() {
|
|
|
"()" => None,
|
|
@@ -173,6 +216,7 @@ pub fn parse(
|
|
|
};
|
|
|
IdlInstruction {
|
|
|
name: ix.ident.to_string().to_mixed_case(),
|
|
|
+ docs: ix.docs.clone(),
|
|
|
accounts,
|
|
|
args,
|
|
|
returns,
|
|
@@ -213,7 +257,7 @@ pub fn parse(
|
|
|
// All user defined types.
|
|
|
let mut accounts = vec![];
|
|
|
let mut types = vec![];
|
|
|
- let ty_defs = parse_ty_defs(&ctx)?;
|
|
|
+ let ty_defs = parse_ty_defs(&ctx, no_docs)?;
|
|
|
|
|
|
let account_structs = parse_accounts(&ctx);
|
|
|
let account_names: HashSet<String> = account_structs
|
|
@@ -247,6 +291,7 @@ pub fn parse(
|
|
|
Ok(Some(Idl {
|
|
|
version,
|
|
|
name: p.name.to_string(),
|
|
|
+ docs: p.docs.clone(),
|
|
|
state,
|
|
|
instructions,
|
|
|
types,
|
|
@@ -380,7 +425,7 @@ fn parse_consts(ctx: &CrateContext) -> Vec<&syn::ItemConst> {
|
|
|
}
|
|
|
|
|
|
// Parse all user defined types in the file.
|
|
|
-fn parse_ty_defs(ctx: &CrateContext) -> Result<Vec<IdlTypeDefinition>> {
|
|
|
+fn parse_ty_defs(ctx: &CrateContext, no_docs: bool) -> Result<Vec<IdlTypeDefinition>> {
|
|
|
ctx.structs()
|
|
|
.filter_map(|item_strct| {
|
|
|
// Only take serializable types
|
|
@@ -407,13 +452,24 @@ fn parse_ty_defs(ctx: &CrateContext) -> Result<Vec<IdlTypeDefinition>> {
|
|
|
}
|
|
|
|
|
|
let name = item_strct.ident.to_string();
|
|
|
+ let doc = if !no_docs {
|
|
|
+ docs::parse(&item_strct.attrs)
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ };
|
|
|
let fields = match &item_strct.fields {
|
|
|
syn::Fields::Named(fields) => fields
|
|
|
.named
|
|
|
.iter()
|
|
|
.map(|f: &syn::Field| {
|
|
|
+ let doc = if !no_docs {
|
|
|
+ docs::parse(&f.attrs)
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ };
|
|
|
Ok(IdlField {
|
|
|
name: f.ident.as_ref().unwrap().to_string().to_mixed_case(),
|
|
|
+ docs: doc,
|
|
|
ty: to_idl_type(ctx, &f.ty),
|
|
|
})
|
|
|
})
|
|
@@ -424,11 +480,17 @@ fn parse_ty_defs(ctx: &CrateContext) -> Result<Vec<IdlTypeDefinition>> {
|
|
|
|
|
|
Some(fields.map(|fields| IdlTypeDefinition {
|
|
|
name,
|
|
|
+ docs: doc,
|
|
|
ty: IdlTypeDefinitionTy::Struct { fields },
|
|
|
}))
|
|
|
})
|
|
|
.chain(ctx.enums().map(|enm| {
|
|
|
let name = enm.ident.to_string();
|
|
|
+ let doc = if !no_docs {
|
|
|
+ docs::parse(&enm.attrs)
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ };
|
|
|
let variants = enm
|
|
|
.variants
|
|
|
.iter()
|
|
@@ -450,8 +512,17 @@ fn parse_ty_defs(ctx: &CrateContext) -> Result<Vec<IdlTypeDefinition>> {
|
|
|
.iter()
|
|
|
.map(|f: &syn::Field| {
|
|
|
let name = f.ident.as_ref().unwrap().to_string();
|
|
|
+ let doc = if !no_docs {
|
|
|
+ docs::parse(&f.attrs)
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ };
|
|
|
let ty = to_idl_type(ctx, &f.ty);
|
|
|
- IdlField { name, ty }
|
|
|
+ IdlField {
|
|
|
+ name,
|
|
|
+ docs: doc,
|
|
|
+ ty,
|
|
|
+ }
|
|
|
})
|
|
|
.collect();
|
|
|
Some(EnumFields::Named(fields))
|
|
@@ -462,6 +533,7 @@ fn parse_ty_defs(ctx: &CrateContext) -> Result<Vec<IdlTypeDefinition>> {
|
|
|
.collect::<Vec<IdlEnumVariant>>();
|
|
|
Ok(IdlTypeDefinition {
|
|
|
name,
|
|
|
+ docs: doc,
|
|
|
ty: IdlTypeDefinitionTy::Enum { variants },
|
|
|
})
|
|
|
}))
|
|
@@ -541,6 +613,7 @@ fn idl_accounts(
|
|
|
accounts: &AccountsStruct,
|
|
|
global_accs: &HashMap<String, AccountsStruct>,
|
|
|
seeds_feature: bool,
|
|
|
+ no_docs: bool,
|
|
|
) -> Vec<IdlAccountItem> {
|
|
|
accounts
|
|
|
.fields
|
|
@@ -550,7 +623,7 @@ fn idl_accounts(
|
|
|
let accs_strct = global_accs.get(&comp_f.symbol).unwrap_or_else(|| {
|
|
|
panic!("Could not resolve Accounts symbol {}", comp_f.symbol)
|
|
|
});
|
|
|
- let accounts = idl_accounts(ctx, accs_strct, global_accs, seeds_feature);
|
|
|
+ let accounts = idl_accounts(ctx, accs_strct, global_accs, seeds_feature, no_docs);
|
|
|
IdlAccountItem::IdlAccounts(IdlAccounts {
|
|
|
name: comp_f.ident.to_string().to_mixed_case(),
|
|
|
accounts,
|
|
@@ -563,6 +636,7 @@ fn idl_accounts(
|
|
|
Ty::Signer => true,
|
|
|
_ => acc.constraints.is_signer(),
|
|
|
},
|
|
|
+ docs: if !no_docs { acc.docs.clone() } else { None },
|
|
|
pda: pda::parse(ctx, accounts, acc, seeds_feature),
|
|
|
}),
|
|
|
})
|