neo_solidity/ir/expressions/calls/
builtins.rs1include!("builtins/helpers.rs");
2include!("builtins/member_access.rs");
3include!("builtins/member_runtime.rs");
4include!("builtins/member_syscalls.rs");
5include!("builtins/member_storage.rs");
6include!("builtins/member_neo.rs");
7include!("builtins/member_nativecalls.rs");
8include!("builtins/resolved.rs");
9
10fn try_lower_builtin_call(
11 func: &Expression,
12 args: &[Expression],
13 ctx: &mut LoweringContext,
14 instructions: &mut Vec<Instruction>,
15) -> Option<bool> {
16 if let Some(result) = try_lower_type_concat(func, args, ctx, instructions) {
19 return Some(result);
20 }
21
22 if let Some(result) = try_lower_member_builtin(func, args, ctx, instructions) {
23 return Some(result);
24 }
25
26 try_lower_resolved_builtin_call(func, args, ctx, instructions)
27}
28
29fn try_lower_type_concat(
35 func: &Expression,
36 args: &[Expression],
37 ctx: &mut LoweringContext,
38 instructions: &mut Vec<Instruction>,
39) -> Option<bool> {
40 let Expression::MemberAccess(_, inner, member) = func else {
41 return None;
42 };
43 if member.name != "concat" {
44 return None;
45 }
46 let is_bytes_or_string = matches!(
48 inner.as_ref(),
49 Expression::Type(_, PtType::DynamicBytes | PtType::String)
50 );
51 if !is_bytes_or_string {
52 return None;
53 }
54
55 if args.is_empty() {
57 instructions.push(Instruction::PushLiteral(LiteralValue::ByteArray(vec![])));
58 return Some(true);
59 }
60
61 let mut success = true;
63 for arg in args {
64 if !lower_expression(arg, ctx, instructions) {
65 success = false;
66 }
67 }
68
69 if success {
70 instructions.push(Instruction::CallBuiltin {
71 builtin: BuiltinCall::BytesConcat,
72 arg_count: args.len(),
73 });
74 }
75
76 Some(success)
77}