Эх сурвалжийг харах

syn: Fix generic type aliases (#2644)

acheron 2 жил өмнө
parent
commit
e1d5e785b8

+ 2 - 0
CHANGELOG.md

@@ -28,6 +28,7 @@ The minor version will be incremented upon a breaking change and the patch versi
 - ts: Add strong type support for `Program.addEventListener` method ([#2627](https://github.com/coral-xyz/anchor/pull/2627)).
 - syn: Add `IdlBuild` trait to implement IDL support for custom types ([#2629](https://github.com/coral-xyz/anchor/pull/2629)).
 - spl: Add `idl-build` feature. IDL build method will not work without enabling this feature when using `anchor-spl` ([#2629](https://github.com/coral-xyz/anchor/pull/2629)).
+- lang: Add support for type aliases in IDLs ([#2637](https://github.com/coral-xyz/anchor/pull/2637)).
 
 ### Fixes
 
@@ -47,6 +48,7 @@ The minor version will be incremented upon a breaking change and the patch versi
 - syn: IDL `parse` method now returns `Result<Idl>` instead of `Result<Option<Idl>>` ([#2582](https://github.com/coral-xyz/anchor/pull/2582)).
 - spl: Update `mpl-token-metadata` dependency to use the client SDK instead of the program crate ([#2632](https://github.com/coral-xyz/anchor/pull/2632)).
 - ts: Remove `base64-js` dependency ([#2635](https://github.com/coral-xyz/anchor/pull/2635)).
+- syn: `IdlTypeDefinitionTy` enum has a new variant `Alias` ([#2637](https://github.com/coral-xyz/anchor/pull/2637)).
 
 ## [0.28.0] - 2023-06-09
 

+ 22 - 14
lang/syn/src/idl/parse/file.rs

@@ -296,6 +296,11 @@ fn parse_consts(ctx: &CrateContext) -> Vec<&syn::ItemConst> {
 fn parse_ty_defs(ctx: &CrateContext, no_docs: bool) -> Result<Vec<IdlTypeDefinition>> {
     ctx.structs()
         .filter_map(|item_strct| {
+            // Only take public types
+            if !matches!(&item_strct.vis, syn::Visibility::Public(_)) {
+                return None;
+            }
+
             // Only take serializable types
             let serializable = item_strct.attrs.iter().any(|attr| {
                 let attr_string = attr.tokens.to_string();
@@ -313,12 +318,6 @@ fn parse_ty_defs(ctx: &CrateContext, no_docs: bool) -> Result<Vec<IdlTypeDefinit
                 return None;
             }
 
-            // Only take public types
-            match &item_strct.vis {
-                syn::Visibility::Public(_) => (),
-                _ => return None,
-            }
-
             let name = item_strct.ident.to_string();
             let doc = if !no_docs {
                 docs::parse(&item_strct.attrs)
@@ -343,7 +342,7 @@ fn parse_ty_defs(ctx: &CrateContext, no_docs: bool) -> Result<Vec<IdlTypeDefinit
                     })
                     .collect::<Result<Vec<IdlField>>>(),
                 syn::Fields::Unnamed(_) => return None,
-                _ => panic!("Empty structs are allowed."),
+                _ => panic!("Empty structs are not allowed."),
             };
 
             Some(fields.map(|fields| IdlTypeDefinition {
@@ -419,6 +418,10 @@ fn parse_ty_defs(ctx: &CrateContext, no_docs: bool) -> Result<Vec<IdlTypeDefinit
             if !matches!(&alias.vis, syn::Visibility::Public(_)) {
                 return None;
             }
+            // Generic type aliases are not currently supported
+            if alias.generics.lt_token.is_some() {
+                return None;
+            }
 
             let name = alias.ident.to_string();
             let doc = if !no_docs {
@@ -426,14 +429,19 @@ fn parse_ty_defs(ctx: &CrateContext, no_docs: bool) -> Result<Vec<IdlTypeDefinit
             } else {
                 None
             };
-            let value = IdlType::from_str(&alias.ty.to_token_stream().to_string()).unwrap();
+            let result = IdlType::from_str(&alias.ty.to_token_stream().to_string()).map(|value| {
+                IdlTypeDefinition {
+                    name,
+                    generics: None,
+                    docs: doc,
+                    ty: IdlTypeDefinitionTy::Alias { value },
+                }
+            });
 
-            Some(Ok(IdlTypeDefinition {
-                name,
-                generics: None,
-                docs: doc,
-                ty: IdlTypeDefinitionTy::Alias { value },
-            }))
+            match &result {
+                Ok(_) => Some(result),
+                Err(_) => None,
+            }
         }))
         .collect()
 }

+ 7 - 0
tests/idl/programs/client-interactions/src/lib.rs

@@ -122,3 +122,10 @@ pub struct TypeAliasAccount {
 pub type TypeAliasU8 = u8;
 pub type TypeAliasU8Array = [TypeAliasU8; 8];
 pub type TypeAliasStruct = MyStruct;
+
+/// Generic type aliases should not get included in the IDL
+pub type TypeAliasNotSupported<'a, T> = NotSupported<'a, T>;
+pub struct NotSupported<'a, T> {
+    _t: T,
+    _s: &'a str,
+}

+ 4 - 4
tests/idl/tests/client-interactions.ts

@@ -141,9 +141,9 @@ describe("Client interactions", () => {
     const account = await program.account.typeAliasAccount.fetch(kp.publicKey);
     assert.strictEqual(account.typeAliasU8, typeAliasU8);
     assert.deepEqual(account.typeAliasU8Array, typeAliasU8Array);
-    assert.strictEqual(typeAliasStruct.u8, 1);
-    assert.strictEqual(typeAliasStruct.u16, 2);
-    assert.strictEqual(typeAliasStruct.u32, 3);
-    assert(typeAliasStruct.u64.eq(typeAliasStruct.u64));
+    assert.strictEqual(account.typeAliasStruct.u8, typeAliasStruct.u8);
+    assert.strictEqual(account.typeAliasStruct.u16, typeAliasStruct.u16);
+    assert.strictEqual(account.typeAliasStruct.u32, typeAliasStruct.u32);
+    assert(account.typeAliasStruct.u64.eq(typeAliasStruct.u64));
   });
 });