@layerzerolabs/framework-solana-anchor-trait 0.2.81 → 0.2.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/examples/shapes/Cargo.lock +22 -22
- package/examples/shapes/Cargo.toml +1 -1
- package/examples/shapes/target/deploy/shapes_ellipse.so +0 -0
- package/examples/shapes/target/deploy/shapes_triangle.so +0 -0
- package/package.json +5 -5
- package/src/assembly.rs +10 -6
- package/src/overrides.rs +1 -1
- package/tests/assembly.rs +120 -0
- package/tests/override.rs +22 -0
|
@@ -89,9 +89,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
|
|
89
89
|
|
|
90
90
|
[[package]]
|
|
91
91
|
name = "anchor-attribute-access-control"
|
|
92
|
-
version = "1.0.
|
|
92
|
+
version = "1.0.1"
|
|
93
93
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
94
|
-
checksum = "
|
|
94
|
+
checksum = "fe55cad36a574c8a048bd4be3f24f438f1888d78098bc137370dab4f6e2173c6"
|
|
95
95
|
dependencies = [
|
|
96
96
|
"proc-macro2",
|
|
97
97
|
"quote",
|
|
@@ -100,9 +100,9 @@ dependencies = [
|
|
|
100
100
|
|
|
101
101
|
[[package]]
|
|
102
102
|
name = "anchor-attribute-account"
|
|
103
|
-
version = "1.0.
|
|
103
|
+
version = "1.0.1"
|
|
104
104
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
105
|
-
checksum = "
|
|
105
|
+
checksum = "4624a1addfa17ef75c5d1eae33b724848420befba0f4f270562daba22704f933"
|
|
106
106
|
dependencies = [
|
|
107
107
|
"anchor-syn",
|
|
108
108
|
"proc-macro2",
|
|
@@ -112,9 +112,9 @@ dependencies = [
|
|
|
112
112
|
|
|
113
113
|
[[package]]
|
|
114
114
|
name = "anchor-attribute-constant"
|
|
115
|
-
version = "1.0.
|
|
115
|
+
version = "1.0.1"
|
|
116
116
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
117
|
-
checksum = "
|
|
117
|
+
checksum = "4043728a3a9f9cd77165d1631d859f22536a5309545ea9803cdabf7eb541af50"
|
|
118
118
|
dependencies = [
|
|
119
119
|
"anchor-syn",
|
|
120
120
|
"quote",
|
|
@@ -123,9 +123,9 @@ dependencies = [
|
|
|
123
123
|
|
|
124
124
|
[[package]]
|
|
125
125
|
name = "anchor-attribute-error"
|
|
126
|
-
version = "1.0.
|
|
126
|
+
version = "1.0.1"
|
|
127
127
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
128
|
-
checksum = "
|
|
128
|
+
checksum = "082f60f03c2dd9c9df1997b9b83ce66e409a46ed701d3e17c157c69006f4058c"
|
|
129
129
|
dependencies = [
|
|
130
130
|
"anchor-syn",
|
|
131
131
|
"quote",
|
|
@@ -134,9 +134,9 @@ dependencies = [
|
|
|
134
134
|
|
|
135
135
|
[[package]]
|
|
136
136
|
name = "anchor-attribute-event"
|
|
137
|
-
version = "1.0.
|
|
137
|
+
version = "1.0.1"
|
|
138
138
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
139
|
-
checksum = "
|
|
139
|
+
checksum = "f7d4cfbfea47ca95da8a7558dd058414e0db563cc56b609e8aa90d41d96c1509"
|
|
140
140
|
dependencies = [
|
|
141
141
|
"anchor-syn",
|
|
142
142
|
"proc-macro2",
|
|
@@ -146,9 +146,9 @@ dependencies = [
|
|
|
146
146
|
|
|
147
147
|
[[package]]
|
|
148
148
|
name = "anchor-attribute-program"
|
|
149
|
-
version = "1.0.
|
|
149
|
+
version = "1.0.1"
|
|
150
150
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
151
|
-
checksum = "
|
|
151
|
+
checksum = "6050e980111673736783492b56da3833628ae9af123bc125d2b5f492f65b9ec8"
|
|
152
152
|
dependencies = [
|
|
153
153
|
"anchor-lang-idl",
|
|
154
154
|
"anchor-syn",
|
|
@@ -161,9 +161,9 @@ dependencies = [
|
|
|
161
161
|
|
|
162
162
|
[[package]]
|
|
163
163
|
name = "anchor-derive-accounts"
|
|
164
|
-
version = "1.0.
|
|
164
|
+
version = "1.0.1"
|
|
165
165
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
166
|
-
checksum = "
|
|
166
|
+
checksum = "b85ae71b15fcd02c1527bca8bd088cc4cdf1c664fdebf0dad3f1d6d454a2eefa"
|
|
167
167
|
dependencies = [
|
|
168
168
|
"anchor-syn",
|
|
169
169
|
"quote",
|
|
@@ -172,9 +172,9 @@ dependencies = [
|
|
|
172
172
|
|
|
173
173
|
[[package]]
|
|
174
174
|
name = "anchor-derive-serde"
|
|
175
|
-
version = "1.0.
|
|
175
|
+
version = "1.0.1"
|
|
176
176
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
177
|
-
checksum = "
|
|
177
|
+
checksum = "826334d127a2ccaed18c1d74c69b8b00cb0e17f99f01b66c92ac108c4792e126"
|
|
178
178
|
dependencies = [
|
|
179
179
|
"anchor-syn",
|
|
180
180
|
"proc-macro-crate",
|
|
@@ -185,9 +185,9 @@ dependencies = [
|
|
|
185
185
|
|
|
186
186
|
[[package]]
|
|
187
187
|
name = "anchor-derive-space"
|
|
188
|
-
version = "1.0.
|
|
188
|
+
version = "1.0.1"
|
|
189
189
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
190
|
-
checksum = "
|
|
190
|
+
checksum = "7b128347e1a8d8f8c14942467a1251e861095c56fe9b7d7f2af09b3f89f7c9a3"
|
|
191
191
|
dependencies = [
|
|
192
192
|
"proc-macro2",
|
|
193
193
|
"quote",
|
|
@@ -196,9 +196,9 @@ dependencies = [
|
|
|
196
196
|
|
|
197
197
|
[[package]]
|
|
198
198
|
name = "anchor-lang"
|
|
199
|
-
version = "1.0.
|
|
199
|
+
version = "1.0.1"
|
|
200
200
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
201
|
-
checksum = "
|
|
201
|
+
checksum = "df469a8bc353440c577504444fc8f53f9f139e61f03981897ecd3e818e8cb3ae"
|
|
202
202
|
dependencies = [
|
|
203
203
|
"anchor-attribute-access-control",
|
|
204
204
|
"anchor-attribute-account",
|
|
@@ -266,9 +266,9 @@ dependencies = [
|
|
|
266
266
|
|
|
267
267
|
[[package]]
|
|
268
268
|
name = "anchor-syn"
|
|
269
|
-
version = "1.0.
|
|
269
|
+
version = "1.0.1"
|
|
270
270
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
271
|
-
checksum = "
|
|
271
|
+
checksum = "3dba8b3c2a352142721a10745bcf1db94bc1dfdc9b313128b6ef5cac4f2be1b4"
|
|
272
272
|
dependencies = [
|
|
273
273
|
"anyhow",
|
|
274
274
|
"bs58",
|
|
@@ -3,7 +3,7 @@ members = ["programs/ellipse", "programs/triangle", "macros"]
|
|
|
3
3
|
resolver = "2"
|
|
4
4
|
|
|
5
5
|
[workspace.dependencies]
|
|
6
|
-
anchor-lang = "1.0.
|
|
6
|
+
anchor-lang = { version = "1.0.1" }
|
|
7
7
|
anchor-trait = { path = "../.." }
|
|
8
8
|
shapes-macros = { path = "macros" }
|
|
9
9
|
mollusk-svm = { version = "0.8", features = ["inner-instructions"] }
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@layerzerolabs/framework-solana-anchor-trait",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.83",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
"rustfmt.toml"
|
|
15
15
|
],
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@layerzerolabs/build-utils-solana": "0.2.
|
|
18
|
-
"@layerzerolabs/tsup-configuration": "0.2.
|
|
19
|
-
"@layerzerolabs/typescript-configuration": "0.2.
|
|
20
|
-
"@layerzerolabs/vm-tooling-solana": "0.2.
|
|
17
|
+
"@layerzerolabs/build-utils-solana": "0.2.83",
|
|
18
|
+
"@layerzerolabs/tsup-configuration": "0.2.83",
|
|
19
|
+
"@layerzerolabs/typescript-configuration": "0.2.83",
|
|
20
|
+
"@layerzerolabs/vm-tooling-solana": "0.2.83"
|
|
21
21
|
},
|
|
22
22
|
"publishConfig": {
|
|
23
23
|
"access": "restricted",
|
package/src/assembly.rs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
use proc_macro2::{Ident, TokenStream};
|
|
4
4
|
use quote::quote;
|
|
5
|
-
use syn::ItemMod;
|
|
5
|
+
use syn::{AttrStyle, ItemMod};
|
|
6
6
|
|
|
7
7
|
use crate::{generation::GeneratedInstructions, overrides::InstructionOverrides, InstructionSet};
|
|
8
8
|
|
|
@@ -38,10 +38,11 @@ impl<Ix: InstructionSet> Assembly<Ix> {
|
|
|
38
38
|
/// wrapper_defs // relocated override handler modules
|
|
39
39
|
/// default_impls // generated default accounts structs + handler impls
|
|
40
40
|
/// extend_macro // macro_rules! for extending default accounts (if configured)
|
|
41
|
-
/// #[
|
|
41
|
+
/// #[outer_mod_attrs] // outer attrs from the source module
|
|
42
42
|
/// #[extra_mod_attrs] // e.g. #[rbac(...)]
|
|
43
43
|
/// #[program] // always innermost — auto-managed by Assembly
|
|
44
44
|
/// mod name {
|
|
45
|
+
/// #![inner_mod_attrs] // inner attrs from the source module (e.g. #![deny(...)])
|
|
45
46
|
/// filtered_items // original items minus relocated handlers
|
|
46
47
|
/// entrypoints // generated instruction entrypoints
|
|
47
48
|
/// }
|
|
@@ -73,9 +74,11 @@ impl<Ix: InstructionSet> Assembly<Ix> {
|
|
|
73
74
|
|
|
74
75
|
let ItemMod { attrs: mod_attrs, vis: mod_vis, ident: mod_ident, .. } = &source_mod;
|
|
75
76
|
|
|
76
|
-
//
|
|
77
|
-
let
|
|
78
|
-
|
|
77
|
+
// Inner attrs (`#![...]`, `//!`) must live inside the body — rustc rejects them outside.
|
|
78
|
+
let (inner_attrs, outer_attrs): (Vec<_>, Vec<_>) = mod_attrs
|
|
79
|
+
.iter()
|
|
80
|
+
.filter(|a| a.path().segments.last().is_none_or(|s| s.ident != "program"))
|
|
81
|
+
.partition(|a| matches!(a.style, AttrStyle::Inner(_)));
|
|
79
82
|
|
|
80
83
|
quote! {
|
|
81
84
|
#prelude
|
|
@@ -83,10 +86,11 @@ impl<Ix: InstructionSet> Assembly<Ix> {
|
|
|
83
86
|
#default_impls
|
|
84
87
|
#extend_macro
|
|
85
88
|
|
|
86
|
-
#(#
|
|
89
|
+
#(#outer_attrs)*
|
|
87
90
|
#extra_mod_attrs
|
|
88
91
|
#[program]
|
|
89
92
|
#mod_vis mod #mod_ident {
|
|
93
|
+
#(#inner_attrs)*
|
|
90
94
|
use super::*;
|
|
91
95
|
#filtered_items
|
|
92
96
|
#entrypoints
|
package/src/overrides.rs
CHANGED
|
@@ -176,7 +176,7 @@ fn has_override_attr(fn_item: &ItemFn, cfg: OverrideConfig) -> bool {
|
|
|
176
176
|
|
|
177
177
|
/// Returns `true` if `attr`'s last path segment matches the configured attribute name.
|
|
178
178
|
fn is_override_attr(attr: &Attribute, cfg: OverrideConfig) -> bool {
|
|
179
|
-
attr.path().
|
|
179
|
+
attr.path().segments.last().is_some_and(|s| s.ident == cfg.attr_name)
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
/// Parses the override target from a function's override attribute.
|
package/tests/assembly.rs
CHANGED
|
@@ -161,6 +161,126 @@ mod tests {
|
|
|
161
161
|
assert!(has_custom_attr, "original module attributes should be preserved");
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
+
#[test]
|
|
165
|
+
fn inner_attrs_routed_into_module_body() {
|
|
166
|
+
// Inner attributes (#![...]) and inner doc comments (//!) on the source module
|
|
167
|
+
// must end up inside the generated mod's body, not outside, otherwise rustc
|
|
168
|
+
// rejects them with "an inner attribute is not permitted in this context".
|
|
169
|
+
let module: syn::ItemMod = syn::parse_quote! {
|
|
170
|
+
mod my_program {
|
|
171
|
+
#![deny(clippy::arithmetic_side_effects)]
|
|
172
|
+
#![allow(unused_variables)]
|
|
173
|
+
//! Module-level doc comment.
|
|
174
|
+
|
|
175
|
+
#[test_instruction]
|
|
176
|
+
pub fn lz_receive(ctx: &mut Context<MyReceive>, params: &LzReceiveParams) -> Result<()> {
|
|
177
|
+
Ok(())
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
let file = assemble_ok(&module, quote! {}, quote! {});
|
|
182
|
+
let (_, m) = find_program_mod(&file).expect("module should exist");
|
|
183
|
+
|
|
184
|
+
let inner_attrs: Vec<_> =
|
|
185
|
+
m.attrs.iter().filter(|a| matches!(a.style, syn::AttrStyle::Inner(_))).collect();
|
|
186
|
+
|
|
187
|
+
let has_deny = inner_attrs
|
|
188
|
+
.iter()
|
|
189
|
+
.any(|a| a.path().segments.last().is_some_and(|seg| seg.ident == "deny"));
|
|
190
|
+
let has_allow = inner_attrs
|
|
191
|
+
.iter()
|
|
192
|
+
.any(|a| a.path().segments.last().is_some_and(|seg| seg.ident == "allow"));
|
|
193
|
+
let has_inner_doc = inner_attrs
|
|
194
|
+
.iter()
|
|
195
|
+
.any(|a| a.path().segments.last().is_some_and(|seg| seg.ident == "doc"));
|
|
196
|
+
|
|
197
|
+
assert!(
|
|
198
|
+
has_deny,
|
|
199
|
+
"#![deny(...)] should be preserved as an inner attr on the generated mod"
|
|
200
|
+
);
|
|
201
|
+
assert!(
|
|
202
|
+
has_allow,
|
|
203
|
+
"#![allow(...)] should be preserved as an inner attr on the generated mod"
|
|
204
|
+
);
|
|
205
|
+
assert!(
|
|
206
|
+
has_inner_doc,
|
|
207
|
+
"//! doc comment should be preserved as an inner attr on the generated mod"
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
// Sanity: no inner-style attribute should appear *before* the generated mod —
|
|
211
|
+
// that would be exactly the position rustc rejects.
|
|
212
|
+
let rendered = quote!(#file).to_string();
|
|
213
|
+
let mod_token = format!("mod {}", m.ident);
|
|
214
|
+
let prefix = rendered
|
|
215
|
+
.split(&mod_token)
|
|
216
|
+
.next()
|
|
217
|
+
.expect("rendered output should contain the module");
|
|
218
|
+
assert!(
|
|
219
|
+
!prefix.contains("# ! ["),
|
|
220
|
+
"no inner-style attribute (#![...]) should appear before the generated mod;\n\
|
|
221
|
+
prefix was:\n{prefix}"
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
#[test]
|
|
226
|
+
fn qualified_program_attr_is_deduplicated() {
|
|
227
|
+
// A previously-expanded macro may have placed a qualified #[program] on the
|
|
228
|
+
// source module (e.g. `#[anchor_lang::prelude::program]`). Assembly always
|
|
229
|
+
// re-emits a canonical `#[program]`, so the qualified form must be filtered
|
|
230
|
+
// out — otherwise the generated module carries two `#[program]` attributes
|
|
231
|
+
// and Anchor's program macro would expand twice.
|
|
232
|
+
let module: syn::ItemMod = syn::parse_quote! {
|
|
233
|
+
#[anchor_lang::prelude::program]
|
|
234
|
+
mod my_program {
|
|
235
|
+
#[test_instruction]
|
|
236
|
+
pub fn lz_receive(ctx: &mut Context<MyReceive>, params: &LzReceiveParams) -> Result<()> {
|
|
237
|
+
Ok(())
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
let file = assemble_ok(&module, quote! {}, quote! {});
|
|
242
|
+
let (_, m) = find_program_mod(&file).expect("module should exist");
|
|
243
|
+
|
|
244
|
+
let program_attr_count = m
|
|
245
|
+
.attrs
|
|
246
|
+
.iter()
|
|
247
|
+
.filter(|a| a.path().segments.last().is_some_and(|s| s.ident == "program"))
|
|
248
|
+
.count();
|
|
249
|
+
assert_eq!(
|
|
250
|
+
program_attr_count, 1,
|
|
251
|
+
"exactly one #[program] attr should remain on the generated mod"
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
#[test]
|
|
256
|
+
fn outer_and_inner_attrs_partitioned_correctly() {
|
|
257
|
+
let module: syn::ItemMod = syn::parse_quote! {
|
|
258
|
+
#[some_outer_attr]
|
|
259
|
+
mod my_program {
|
|
260
|
+
#![deny(clippy::arithmetic_side_effects)]
|
|
261
|
+
|
|
262
|
+
#[test_instruction]
|
|
263
|
+
pub fn lz_receive(ctx: &mut Context<MyReceive>, params: &LzReceiveParams) -> Result<()> {
|
|
264
|
+
Ok(())
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
let file = assemble_ok(&module, quote! {}, quote! {});
|
|
269
|
+
let (_, m) = find_program_mod(&file).expect("module should exist");
|
|
270
|
+
|
|
271
|
+
let has_outer = m.attrs.iter().any(|a| {
|
|
272
|
+
matches!(a.style, syn::AttrStyle::Outer)
|
|
273
|
+
&& a.path().segments.last().is_some_and(|seg| seg.ident == "some_outer_attr")
|
|
274
|
+
});
|
|
275
|
+
let has_inner_deny = m.attrs.iter().any(|a| {
|
|
276
|
+
matches!(a.style, syn::AttrStyle::Inner(_))
|
|
277
|
+
&& a.path().segments.last().is_some_and(|seg| seg.ident == "deny")
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
assert!(has_outer, "outer attribute should be preserved on the generated mod");
|
|
281
|
+
assert!(has_inner_deny, "inner attribute should be preserved on the generated mod");
|
|
282
|
+
}
|
|
283
|
+
|
|
164
284
|
#[test]
|
|
165
285
|
fn filtered_items_inside_module() {
|
|
166
286
|
let module = module_with_override_and_extras();
|
package/tests/override.rs
CHANGED
|
@@ -121,6 +121,28 @@ mod tests {
|
|
|
121
121
|
assert!(overrides.get(TestIx::LzReceive).is_none());
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
#[test]
|
|
125
|
+
fn qualified_attribute_path_recognized_as_override() {
|
|
126
|
+
// A qualified attribute path like `#[crate::test_instruction]` should still
|
|
127
|
+
// register as an override. `Path::is_ident` is strict-1-segment and would
|
|
128
|
+
// silently miss this, leaving the function as a bare item and emitting the
|
|
129
|
+
// default entrypoint instead.
|
|
130
|
+
let module: syn::ItemMod = syn::parse_quote! {
|
|
131
|
+
mod my_program {
|
|
132
|
+
#[crate::test_instruction]
|
|
133
|
+
pub fn set_peer(ctx: &mut Context<MyAccounts>, params: &SetPeerParams) -> Result<()> {
|
|
134
|
+
Ok(())
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
let overrides = collect_ok(&module);
|
|
139
|
+
|
|
140
|
+
assert!(
|
|
141
|
+
overrides.get(TestIx::SetPeer).is_some(),
|
|
142
|
+
"qualified #[crate::test_instruction] should register as a SetPeer override"
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
124
146
|
#[test]
|
|
125
147
|
fn multiple_unique_overrides() {
|
|
126
148
|
let module: syn::ItemMod = syn::parse_quote! {
|