forked from neo-project/neo-devpack-dotnet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInitializerExpression.cs
75 lines (70 loc) · 3.03 KB
/
InitializerExpression.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Copyright (C) 2015-2023 The Neo Project.
//
// The Neo.Compiler.CSharp is free software distributed under the MIT
// software license, see the accompanying file LICENSE in the main directory
// of the project or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
extern alias scfx;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Neo.VM;
using System.Linq;
namespace Neo.Compiler;
partial class MethodConvert
{
/// <summary>
/// Converts an InitialValue attribute into OpCodes.
/// </summary>
/// <param name="model">The semantic model providing context and information about InitialValue expression.</param>
/// <param name="expression">The syntax representation of the InitialValue expression statement being converted.</param>
/// <example>
/// Specifies an initial value for a static field within a smart contract,
/// Example of initializing a UInt160 field with a Hash160 address
/// <code>
/// [InitialValue("NVg7LjGcUSrgxgjX3zEgqaksfMaiS8Z6e1", ContractParameterType.Hash160)]
/// static readonly UInt160 Owner = default;
/// </code>
/// </example>
/// <seealso href="https://github.com/neo-project/neo-devpack-dotnet/blob/master/src/Neo.SmartContract.Framework/Attributes/InitialValueAttribute.cs">InitialValueAttribute</seealso>
private void ConvertInitializerExpression(SemanticModel model, InitializerExpressionSyntax expression)
{
IArrayTypeSymbol type = (IArrayTypeSymbol)model.GetTypeInfo(expression).ConvertedType!;
ConvertInitializerExpression(model, type, expression);
}
private void ConvertInitializerExpression(SemanticModel model, IArrayTypeSymbol type, InitializerExpressionSyntax expression)
{
if (type.ElementType.SpecialType == SpecialType.System_Byte)
{
Optional<object?>[] values = expression.Expressions.Select(p => model.GetConstantValue(p)).ToArray();
if (values.Any(p => !p.HasValue))
{
Push(values.Length);
AddInstruction(OpCode.NEWBUFFER);
for (int i = 0; i < expression.Expressions.Count; i++)
{
AddInstruction(OpCode.DUP);
Push(i);
ConvertExpression(model, expression.Expressions[i]);
AddInstruction(OpCode.SETITEM);
}
}
else
{
byte[] data = values.Select(p => (byte)System.Convert.ChangeType(p.Value, typeof(byte))!).ToArray();
Push(data);
ChangeType(VM.Types.StackItemType.Buffer);
}
}
else
{
for (int i = expression.Expressions.Count - 1; i >= 0; i--)
ConvertExpression(model, expression.Expressions[i]);
Push(expression.Expressions.Count);
AddInstruction(OpCode.PACK);
}
}
}