neo_solidity/ir/expressions/
variable.rs1fn lower_variable_expression(
2 identifier: &Identifier,
3 ctx: &mut LoweringContext,
4 instructions: &mut Vec<Instruction>,
5) -> bool {
6 if identifier.name == "this" {
7 instructions.push(Instruction::CallBuiltin {
8 builtin: BuiltinCall::Syscall("System.Runtime.GetExecutingScriptHash".to_string()),
9 arg_count: 0,
10 });
11 return true;
12 }
13 if identifier.name == "block" || identifier.name == "msg" {
14 instructions.push(Instruction::PushLiteral(LiteralValue::Integer(BigInt::zero())));
15 return true;
16 }
17 if identifier.name == "super" {
18 ctx.record_error_with_suggestion(
22 "the 'super' keyword can only be used in member-call expressions (super.method())",
23 "use super.methodName() to call a parent contract's function, or inline the parent logic directly",
24 );
25 instructions.push(Instruction::PushLiteral(LiteralValue::Integer(BigInt::zero())));
26 return false;
27 }
28 if let Some(alias) = ctx.storage_alias(&identifier.name).cloned() {
29 return emit_storage_load(&alias, ctx, instructions);
30 }
31 if let Some(index) = ctx.param_index_map.get(&identifier.name) {
32 instructions.push(Instruction::LoadParameter(*index));
33 true
34 } else if let Some(index) = ctx.resolve_local(&identifier.name) {
35 instructions.push(Instruction::LoadLocal(index));
36 true
37 } else if let Some(index) = ctx.state_index_map.get(&identifier.name) {
38 let state_index = *index;
39 let state_type = ctx.state_type(state_index).cloned();
40 let const_initializer = ctx.state_metadata(*index).and_then(|meta| {
41 if meta.is_constant {
42 meta.initializer.clone()
43 } else {
44 None
45 }
46 });
47 if let Some(initializer) = const_initializer {
48 if matches!(state_type.as_ref(), Some(ValueType::Address)) {
52 if let Some(bytes) = address_bytes_le_from_expression(&initializer) {
53 instructions.push(Instruction::PushLiteral(LiteralValue::Address(bytes)));
54 return true;
55 }
56 }
57
58 return lower_expression(&initializer, ctx, instructions);
59 }
60
61 if let Some(vt @ ValueType::Struct { .. }) = state_type {
64 let reference = StorageReference {
65 state_index,
66 key_expressions: Vec::new(),
67 key_types: Vec::new(),
68 value_type: vt,
69 field_path: Vec::new(),
70 };
71 return emit_storage_load(&reference, ctx, instructions);
72 }
73
74 instructions.push(Instruction::LoadState(state_index));
75 true
76 } else {
77 ctx.record_error_with_suggestion(
78 format!("unknown identifier '{}'", identifier.name),
79 "check spelling or ensure the variable is declared in the same contract or an imported library",
80 );
81 false
82 }
83}