Skip to content

Commit

Permalink
lang: Fix parsing for bytes literals in the IDL (coral-xyz#2261)
Browse files Browse the repository at this point in the history
* lang: Fix parsing of some constants

* Fix lint + changelog
  • Loading branch information
Aursen authored and henrye committed Dec 6, 2022
1 parent b576a2a commit 8067711
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ The minor version will be incremented upon a breaking change and the patch versi

### Fixes

* lang: Fix parsing for bytes literals in the IDL. ([#2261](https://github.com/coral-xyz/anchor/pull/2261))
* lang: Fix IDL `seed` generation for byte string literals. ([#2125](https://github.com/coral-xyz/anchor/pull/2125))
* ts: Update seeds inference to allow nested user defined structs within the seeds ([#2198](https://github.com/coral-xyz/anchor/pull/2198))

Expand Down
41 changes: 36 additions & 5 deletions lang/syn/src/idl/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ use heck::MixedCase;
use quote::ToTokens;
use std::collections::{HashMap, HashSet};
use std::path::Path;
use syn::{
Expr, ExprLit, ItemConst,
Lit::{Byte, ByteStr},
};

const DERIVE_NAME: &str = "Accounts";
// TODO: share this with `anchor_lang` crate.
Expand Down Expand Up @@ -281,11 +285,7 @@ pub fn parse(

let constants = parse_consts(&ctx)
.iter()
.map(|c: &&syn::ItemConst| IdlConst {
name: c.ident.to_string(),
ty: c.ty.to_token_stream().to_string().parse().unwrap(),
value: c.expr.to_token_stream().to_string().parse().unwrap(),
})
.map(|c: &&syn::ItemConst| to_idl_const(c))
.collect::<Vec<IdlConst>>();

Ok(Some(Idl {
Expand Down Expand Up @@ -615,6 +615,37 @@ fn to_idl_type(ctx: &CrateContext, ty: &syn::Type) -> IdlType {
tts_string.parse().unwrap()
}

// TODO parse other issues
fn to_idl_const(item: &ItemConst) -> IdlConst {
let name = item.ident.to_string();

if let Expr::Lit(ExprLit { lit, .. }) = &*item.expr {
match lit {
ByteStr(lit_byte_str) => {
return IdlConst {
name,
ty: IdlType::Bytes,
value: format!("{:?}", lit_byte_str.value()),
}
}
Byte(lit_byte) => {
return IdlConst {
name,
ty: IdlType::U8,
value: lit_byte.value().to_string(),
}
}
_ => (),
}
}

IdlConst {
name,
ty: item.ty.to_token_stream().to_string().parse().unwrap(),
value: item.expr.to_token_stream().to_string().parse().unwrap(),
}
}

fn idl_accounts(
ctx: &CrateContext,
accounts: &AccountsStruct,
Expand Down
4 changes: 4 additions & 0 deletions tests/misc/programs/misc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ declare_id!("3TEqcc8xhrhdspwbvoamUJe2borm4Nr72JxL66k6rgrh");
pub const BASE: u128 = 1_000_000;
#[constant]
pub const DECIMALS: u8 = 6;
#[constant]
pub const BYTES_STR: &[u8] = b"test";
#[constant]
pub const BYTE_STR: u8 = b't';
pub const NO_IDL: u16 = 55;

#[program]
Expand Down
19 changes: 19 additions & 0 deletions tests/misc/tests/misc/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,25 @@ describe("misc", () => {
);
});

it("Should include BYTES_STR const in IDL", async () => {
assert.isDefined(
miscIdl.constants.find(
(c) =>
c.name === "BYTES_STR" &&
c.type === "bytes" &&
c.value === "[116, 101, 115, 116]"
)
);
});

it("Should include BYTE_STR const in IDL", async () => {
assert.isDefined(
miscIdl.constants.find(
(c) => c.name === "BYTE_STR" && c.type === "u8" && c.value === "116"
)
);
});

it("Should not include NO_IDL const in IDL", async () => {
assert.isUndefined(miscIdl.constants.find((c) => c.name === "NO_IDL"));
});
Expand Down

0 comments on commit 8067711

Please sign in to comment.