diff --git a/src/Neo.Compiler.CSharp/MethodConvert/Expression/ObjectCreationExpression.cs b/src/Neo.Compiler.CSharp/MethodConvert/Expression/ObjectCreationExpression.cs index 10c4e3f0d..61bd2e145 100644 --- a/src/Neo.Compiler.CSharp/MethodConvert/Expression/ObjectCreationExpression.cs +++ b/src/Neo.Compiler.CSharp/MethodConvert/Expression/ObjectCreationExpression.cs @@ -16,6 +16,8 @@ using Neo.VM; using System; using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Neo.Compiler; @@ -48,6 +50,76 @@ private void ConvertObjectCreationExpression(SemanticModel model, BaseObjectCrea private void ConvertObjectCreationExpressionInitializer(SemanticModel model, InitializerExpressionSyntax initializer) { + // Handle different types of initializer expressions: + // + // ObjectInitializerExpression: + // Example: new Person { Name = "John", Age = 30 } + // Used for initializing properties of an object. + // + // CollectionInitializerExpression: + // Example: new List { 1, 2, 3 } + // Used for initializing collections like lists or sets. + // + // ArrayInitializerExpression: + // Example: new int[] { 1, 2, 3 } + // Used for initializing arrays. + // + // ComplexElementInitializerExpression: + // Example: new Dictionary { { "one", 1 }, { "two", 2 } } + // Used for initializing complex elements like dictionary entries. + // + // NullLiteralExpression: + // Example: new Person { Name = null } + // Used when explicitly setting a property to null in an initializer. + + if (initializer.IsKind(SyntaxKind.CollectionInitializerExpression)) + { + ITypeSymbol type; + if (initializer.Expressions.Count > 0) + { + var firstExpression = initializer.Expressions[0]; + var typeInfo = model.GetTypeInfo(firstExpression); + type = typeInfo.Type!; + } + else + { + // Handle empty collection case if necessary + throw new CompilationException(initializer, DiagnosticId.SyntaxNotSupported, "Cannot determine item type from an empty collection initializer."); + } + + AddInstruction(OpCode.DROP); + if (type.SpecialType == SpecialType.System_Byte) + { + var values = initializer.Expressions.Select(p => model.GetConstantValue(p)).ToArray(); + if (values.Any(p => !p.HasValue)) + { + Push(values.Length); + AddInstruction(OpCode.NEWBUFFER); + for (var i = 0; i < initializer.Expressions.Count; i++) + { + AddInstruction(OpCode.DUP); + Push(i); + ConvertExpression(model, initializer.Expressions[i]); + AddInstruction(OpCode.SETITEM); + } + } + else + { + var data = values.Select(p => (byte)System.Convert.ChangeType(p.Value, typeof(byte))!).ToArray(); + Push(data); + ChangeType(VM.Types.StackItemType.Buffer); + } + } + else + { + for (var i = initializer.Expressions.Count - 1; i >= 0; i--) + ConvertExpression(model, initializer.Expressions[i]); + Push(initializer.Expressions.Count); + AddInstruction(OpCode.PACK); + } + return; + } + foreach (ExpressionSyntax e in initializer.Expressions) { if (e is not AssignmentExpressionSyntax ae) @@ -63,9 +135,38 @@ private void ConvertObjectCreationExpressionInitializer(SemanticModel model, Ini AddInstruction(OpCode.SETITEM); break; case IPropertySymbol property: - ConvertExpression(model, ae.Right); - AddInstruction(OpCode.OVER); - CallMethodWithConvention(model, property.SetMethod!, CallingConvention.Cdecl); + // Special handling for Map and List initialization is required due to their unique initialization syntax and behavior. + // Map and List properties are not defined explicitly like regular types + + // Examples: + // Map: new Map { ["key"] = 42 }; + // This is equivalent to: map["key"] = 42; + // Regular: new MyClass { Property = value }; + // This uses the standard property setter. + if (property.ContainingType.Name is "Map") + { + // Duplicate the object reference for Map and List + AddInstruction(OpCode.DUP); + + if (ae.Left is ImplicitElementAccessSyntax elementAccess) + { + ConvertExpression(model, elementAccess.ArgumentList.Arguments[0].Expression); + } + else + { + ConvertExpression(model, ae.Left); + } + // Convert the value to be assigned (for both Map and List) + ConvertExpression(model, ae.Right); + AddInstruction(OpCode.SETITEM); + } + else + { + // For regular properties: + ConvertExpression(model, ae.Right); + AddInstruction(OpCode.OVER); + CallMethodWithConvention(model, property.SetMethod!, CallingConvention.Cdecl); + } break; default: throw new CompilationException(ae.Left, DiagnosticId.SyntaxNotSupported, $"Unsupported symbol: {symbol}"); diff --git a/tests/Neo.Compiler.CSharp.TestContracts/Contract_PropertyMethod.cs b/tests/Neo.Compiler.CSharp.TestContracts/Contract_PropertyMethod.cs index 6f69adef9..593330ace 100644 --- a/tests/Neo.Compiler.CSharp.TestContracts/Contract_PropertyMethod.cs +++ b/tests/Neo.Compiler.CSharp.TestContracts/Contract_PropertyMethod.cs @@ -1,3 +1,5 @@ +using Neo.SmartContract.Framework; + namespace Neo.Compiler.CSharp.TestContracts; public class Contract_PropertyMethod : SmartContract.Framework.SmartContract @@ -13,6 +15,30 @@ public static void testProperty2() var p = new Person("NEO3", 10); } + public static Person testProperty3() + { + return new Person() + { + Name = "NEO3", + }; + } + + public static Map testProperty4() + { + return new Map() + { + ["Name"] = "NEO3", + }; + } + + public static List testProperty5() + { + return new List() + { + 1, 2, 3, 4, 5 + }; + } + public static (string, int, string) testPropertyInit() { var p = new Person("NEO3", 10) { Address = "123 Blockchain St" }; @@ -30,5 +56,9 @@ public Person(string name, int age) Name = name; Age = age; } + + public Person() + { + } } } diff --git a/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_NEP11.cs b/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_NEP11.cs index effba1bf2..6721deb42 100644 --- a/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_NEP11.cs +++ b/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_NEP11.cs @@ -10,12 +10,12 @@ public abstract class Contract_NEP11(Neo.SmartContract.Testing.SmartContractInit { #region Compiled data - public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_NEP11"",""groups"":[],""features"":{},""supportedstandards"":[""NEP-11""],""abi"":{""methods"":[{""name"":""symbol"",""parameters"":[],""returntype"":""String"",""offset"":0,""safe"":true},{""name"":""decimals"",""parameters"":[],""returntype"":""Integer"",""offset"":7,""safe"":true},{""name"":""totalSupply"",""parameters"":[],""returntype"":""Integer"",""offset"":9,""safe"":true},{""name"":""balanceOf"",""parameters"":[{""name"":""owner"",""type"":""Hash160""}],""returntype"":""Integer"",""offset"":35,""safe"":true},{""name"":""ownerOf"",""parameters"":[{""name"":""tokenId"",""type"":""ByteArray""}],""returntype"":""Hash160"",""offset"":218,""safe"":true},{""name"":""properties"",""parameters"":[{""name"":""tokenId"",""type"":""ByteArray""}],""returntype"":""Map"",""offset"":377,""safe"":true},{""name"":""tokens"",""parameters"":[],""returntype"":""InteropInterface"",""offset"":419,""safe"":true},{""name"":""tokensOf"",""parameters"":[{""name"":""owner"",""type"":""Hash160""}],""returntype"":""InteropInterface"",""offset"":447,""safe"":true},{""name"":""transfer"",""parameters"":[{""name"":""to"",""type"":""Hash160""},{""name"":""tokenId"",""type"":""ByteArray""},{""name"":""data"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":536,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":837,""safe"":false}],""events"":[{""name"":""Transfer"",""parameters"":[{""name"":""from"",""type"":""Hash160""},{""name"":""to"",""type"":""Hash160""},{""name"":""amount"",""type"":""Integer""},{""name"":""tokenId"",""type"":""ByteArray""}]}]},""permissions"":[{""contract"":""0x726cb6e0cd8628a1350a611384688911ab75f51b"",""methods"":[""sha256""]},{""contract"":""0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0"",""methods"":[""deserialize"",""serialize""]},{""contract"":""0xfffdc93764dbaddd97c48f252a53ea4643faa3fd"",""methods"":[""getContract""]},{""contract"":""*"",""methods"":[""onNEP11Payment""]}],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}"); + public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_NEP11"",""groups"":[],""features"":{},""supportedstandards"":[""NEP-11""],""abi"":{""methods"":[{""name"":""symbol"",""parameters"":[],""returntype"":""String"",""offset"":0,""safe"":true},{""name"":""decimals"",""parameters"":[],""returntype"":""Integer"",""offset"":7,""safe"":true},{""name"":""totalSupply"",""parameters"":[],""returntype"":""Integer"",""offset"":9,""safe"":true},{""name"":""balanceOf"",""parameters"":[{""name"":""owner"",""type"":""Hash160""}],""returntype"":""Integer"",""offset"":35,""safe"":true},{""name"":""ownerOf"",""parameters"":[{""name"":""tokenId"",""type"":""ByteArray""}],""returntype"":""Hash160"",""offset"":218,""safe"":true},{""name"":""properties"",""parameters"":[{""name"":""tokenId"",""type"":""ByteArray""}],""returntype"":""Map"",""offset"":377,""safe"":true},{""name"":""tokens"",""parameters"":[],""returntype"":""InteropInterface"",""offset"":424,""safe"":true},{""name"":""tokensOf"",""parameters"":[{""name"":""owner"",""type"":""Hash160""}],""returntype"":""InteropInterface"",""offset"":452,""safe"":true},{""name"":""transfer"",""parameters"":[{""name"":""to"",""type"":""Hash160""},{""name"":""tokenId"",""type"":""ByteArray""},{""name"":""data"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":541,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":842,""safe"":false}],""events"":[{""name"":""Transfer"",""parameters"":[{""name"":""from"",""type"":""Hash160""},{""name"":""to"",""type"":""Hash160""},{""name"":""amount"",""type"":""Integer""},{""name"":""tokenId"",""type"":""ByteArray""}]}]},""permissions"":[{""contract"":""0x726cb6e0cd8628a1350a611384688911ab75f51b"",""methods"":[""sha256""]},{""contract"":""0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0"",""methods"":[""deserialize"",""serialize""]},{""contract"":""0xfffdc93764dbaddd97c48f252a53ea4643faa3fd"",""methods"":[""getContract""]},{""contract"":""*"",""methods"":[""onNEP11Payment""]}],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}"); /// /// Optimization: "All" /// - public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATA7znO4OTpJcbCoGp54UQN2G/OrAtkZXNlcmlhbGl6ZQEAAQ/A7znO4OTpJcbCoGp54UQN2G/OrAlzZXJpYWxpemUBAAEP/aP6Q0bqUyolj8SX3a3bZDfJ/f8LZ2V0Q29udHJhY3QBAAEPG/V1qxGJaIQTYQo1oSiGzeC2bHIGc2hhMjU2AQABDwAA/UgDDARURVNUQBBAWNgmFwwBAEH2tGviQZJd6DFK2CYERRBKYEBXAQF4cGgLlyYFCCINeErZKFDKABSzq6omJQwgVGhlIGFyZ3VtZW50ICJvd25lciIgaXMgaW52YWxpZC46QZv2Z84REYhOEFHQUBLAcHhowUVTi1BBkl3oMUrYJgRFENshQFcCAkGb9mfOERGIThBR0FASwHB4aMFFU4tQQZJd6DFK2CYERRDbIXFpeZ5xaRC1JgQJQGkQsyYQeGjBRVOLUEEvWMXtIg9peGjBRVOLUEHmPxiECEBXAwF4ygBAtyY8DDdUaGUgYXJndW1lbnQgInRva2VuSWQiIHNob3VsZCBiZSA2NCBvciBsZXNzIGJ5dGVzIGxvbmcuOhMRiE4QUdBBm/ZnzhLAcHhowUVTi1BBkl3oMUrYJjRFDC5UaGUgdG9rZW4gd2l0aCBnaXZlbiAidG9rZW5JZCIgZG9lcyBub3QgZXhpc3QuOnFpNwAAcmoQzkBXAgETEYhOEFHQQZv2Z84SwHB4aMFFU4tQQZJd6DE3AABxyGkRzktT0EBXAQATEYhOEFHQQZv2Z84SwHATaMFFQd8wuJpAVwEBeHBoC5cmBQgiDXhK2ShQygAUs6uqJiQMH1RoZSBhcmd1bWVudCAib3duZXIiIGlzIGludmFsaWQ6FBGIThBR0EGb9mfOEsBwE3howUVTi1BB3zC4mkBXAwN4cGgLlyYFCCINeErZKFDKABSzq6omIgwdVGhlIGFyZ3VtZW50ICJ0byIgaXMgaW52YWxpZC46ExGIThBR0EGb9mfOEsBweWjBRVOLUEGSXegxNwAAcWkQznJqQfgn7IyqJgQJQGp4mCYleEppEFHQRWk3AQBKeWjBRVOLUEHmPxiERQ95ajQPEXl4NAp6eXhqNEUIQFcCA3p4NdD9//9FQZv2Z84UEYhOEFHQUBLAcHh5i9socXoQtyYQEGlowUVTi1BB5j8YhEBpaMFFU4tQQS9Yxe1AVwEEwkp4z0p5z0oRz0p6zwwIVHJhbnNmZXJBlQFvYXlwaAuXqiQFCSILeTcCAHBoC5eqJiB7ehF4FMAfDA5vbk5FUDExUGF5bWVudHlBYn1bUkVAVgFAfGetTA==")); + public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATA7znO4OTpJcbCoGp54UQN2G/OrAtkZXNlcmlhbGl6ZQEAAQ/A7znO4OTpJcbCoGp54UQN2G/OrAlzZXJpYWxpemUBAAEP/aP6Q0bqUyolj8SX3a3bZDfJ/f8LZ2V0Q29udHJhY3QBAAEPG/V1qxGJaIQTYQo1oSiGzeC2bHIGc2hhMjU2AQABDwAA/U0DDARURVNUQBBAWNgmFwwBAEH2tGviQZJd6DFK2CYERRBKYEBXAQF4cGgLlyYFCCINeErZKFDKABSzq6omJQwgVGhlIGFyZ3VtZW50ICJvd25lciIgaXMgaW52YWxpZC46QZv2Z84REYhOEFHQUBLAcHhowUVTi1BBkl3oMUrYJgRFENshQFcCAkGb9mfOERGIThBR0FASwHB4aMFFU4tQQZJd6DFK2CYERRDbIXFpeZ5xaRC1JgQJQGkQsyYQeGjBRVOLUEEvWMXtIg9peGjBRVOLUEHmPxiECEBXAwF4ygBAtyY8DDdUaGUgYXJndW1lbnQgInRva2VuSWQiIHNob3VsZCBiZSA2NCBvciBsZXNzIGJ5dGVzIGxvbmcuOhMRiE4QUdBBm/ZnzhLAcHhowUVTi1BBkl3oMUrYJjRFDC5UaGUgdG9rZW4gd2l0aCBnaXZlbiAidG9rZW5JZCIgZG9lcyBub3QgZXhpc3QuOnFpNwAAcmoQzkBXAgETEYhOEFHQQZv2Z84SwHB4aMFFU4tQQZJd6DE3AABxyEoMBG5hbWVpEc7QQFcBABMRiE4QUdBBm/ZnzhLAcBNowUVB3zC4mkBXAQF4cGgLlyYFCCINeErZKFDKABSzq6omJAwfVGhlIGFyZ3VtZW50ICJvd25lciIgaXMgaW52YWxpZDoUEYhOEFHQQZv2Z84SwHATeGjBRVOLUEHfMLiaQFcDA3hwaAuXJgUIIg14StkoUMoAFLOrqiYiDB1UaGUgYXJndW1lbnQgInRvIiBpcyBpbnZhbGlkLjoTEYhOEFHQQZv2Z84SwHB5aMFFU4tQQZJd6DE3AABxaRDOcmpB+CfsjKomBAlAaniYJiV4SmkQUdBFaTcBAEp5aMFFU4tQQeY/GIRFD3lqNA8ReXg0Cnp5eGo0RQhAVwIDeng1y/3//0VBm/ZnzhQRiE4QUdBQEsBweHmL2yhxehC3JhAQaWjBRVOLUEHmPxiEQGlowUVTi1BBL1jF7UBXAQTCSnjPSnnPShHPSnrPDAhUcmFuc2ZlckGVAW9heXBoC5eqJAUJIgt5NwIAcGgLl6omIHt6EXgUwB8MDm9uTkVQMTFQYXltZW50eUFifVtSRUBWAUB17R06")); #endregion diff --git a/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_PropertyMethod.cs b/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_PropertyMethod.cs index dc3d58d39..d881bac62 100644 --- a/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_PropertyMethod.cs +++ b/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_PropertyMethod.cs @@ -10,12 +10,12 @@ public abstract class Contract_PropertyMethod(Neo.SmartContract.Testing.SmartCon { #region Compiled data - public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_PropertyMethod"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""testProperty"",""parameters"":[],""returntype"":""Array"",""offset"":0,""safe"":false},{""name"":""testProperty2"",""parameters"":[],""returntype"":""Void"",""offset"":50,""safe"":false},{""name"":""testPropertyInit"",""parameters"":[],""returntype"":""Array"",""offset"":71,""safe"":false}],""events"":[]},""permissions"":[],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}"); + public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_PropertyMethod"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""testProperty"",""parameters"":[],""returntype"":""Array"",""offset"":0,""safe"":false},{""name"":""testProperty2"",""parameters"":[],""returntype"":""Void"",""offset"":50,""safe"":false},{""name"":""testProperty3"",""parameters"":[],""returntype"":""Any"",""offset"":71,""safe"":false},{""name"":""testProperty4"",""parameters"":[],""returntype"":""Map"",""offset"":94,""safe"":false},{""name"":""testProperty5"",""parameters"":[],""returntype"":""Array"",""offset"":110,""safe"":false},{""name"":""testPropertyInit"",""parameters"":[],""returntype"":""Array"",""offset"":120,""safe"":false}],""events"":[]},""permissions"":[],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}"); /// /// Optimization: "All" /// - public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAINXAQALEAsTwBoMBE5FTzMSTTQPcMVKaBDOz0poEc7PQFcAA3lKeBBR0EV6SngRUdBFQFcBAAsQCxPAGgwETkVPMxJNNN1wQFcBAAsQCxPAGgwETkVPMxJNNMgMETEyMyBCbG9ja2NoYWluIFN0SxJR0HDFSmgQzs9KaBHOz0poEs7PQGh8TO4=")); + public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALRXAQALEAsTwBoMBE5FTzMSTTQPcMVKaBDOz0poEc7PQFcAA3lKeBBR0EV6SngRUdBFQFcBAAsQCxPAGgwETkVPMxJNNN1wQAsQCxPASjQNDARORU8zSxBR0EBXAAFAyEoMBE5hbWUMBE5FTzPQQMJFFRQTEhEVwEBXAQALEAsTwBoMBE5FTzMSTTSXDBExMjMgQmxvY2tjaGFpbiBTdEsSUdBwxUpoEM7PSmgRzs9KaBLOz0Dp1QFJ")); #endregion @@ -33,6 +33,24 @@ public abstract class Contract_PropertyMethod(Neo.SmartContract.Testing.SmartCon [DisplayName("testProperty2")] public abstract void TestProperty2(); + /// + /// Unsafe method + /// + [DisplayName("testProperty3")] + public abstract object? TestProperty3(); + + /// + /// Unsafe method + /// + [DisplayName("testProperty4")] + public abstract IDictionary? TestProperty4(); + + /// + /// Unsafe method + /// + [DisplayName("testProperty5")] + public abstract IList? TestProperty5(); + /// /// Unsafe method /// diff --git a/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_Property_Method.cs b/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_Property_Method.cs index 14880fc37..33ec31a2c 100644 --- a/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_Property_Method.cs +++ b/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_Property_Method.cs @@ -1,7 +1,9 @@ +using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.SmartContract.Testing; using Neo.VM.Types; using System.Numerics; +using Array = Neo.VM.Types.Array; namespace Neo.Compiler.CSharp.UnitTests { @@ -27,6 +29,46 @@ public void TestPropertyMethod2() // No errors } + [TestMethod] + public void TestPropertyMethod3() + { + var person = Contract.TestProperty3()! as Array; + AssertGasConsumed(1309080); // Adjust this value based on actual gas consumption + + Assert.IsNotNull(person); + Assert.AreEqual(3, person.Count); + Assert.AreEqual((person[0] as StackItem)!.GetString(), "NEO3"); + Assert.AreEqual(person[1], new BigInteger(0)); + } + + [TestMethod] + public void TestPropertyMethod4() + { + var map = Contract.TestProperty4()!; + AssertGasConsumed(1230570); // Adjust this value based on actual gas consumption + + Assert.IsNotNull(map); + Assert.AreEqual(1, map.Count); + + var key = (ByteString)"Name"; + Assert.IsTrue(map.ContainsKey(key)); + Assert.AreEqual((map[key] as StackItem)!.GetString(), "NEO3"); + } + + [TestMethod] + public void TestPropertyMethod5() + { + var list = Contract.TestProperty5()!; + AssertGasConsumed(1046190); // Adjust this value based on actual gas consumption + + Assert.IsNotNull(list); + Assert.AreEqual(5, list.Count); + for (var i = 0; i < 5; i++) + { + Assert.AreEqual(i + 1, (int)(BigInteger)list[i]); + } + } + [TestMethod] public void TestPropertyInit() { diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestingArtifacts/Contract_SupportedStandard11Enum.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestingArtifacts/Contract_SupportedStandard11Enum.cs index a1bef0039..bb6376a2c 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestingArtifacts/Contract_SupportedStandard11Enum.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestingArtifacts/Contract_SupportedStandard11Enum.cs @@ -10,12 +10,12 @@ public abstract class Contract_SupportedStandard11Enum(Neo.SmartContract.Testing { #region Compiled data - public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_SupportedStandard11Enum"",""groups"":[],""features"":{},""supportedstandards"":[""NEP-11""],""abi"":{""methods"":[{""name"":""symbol"",""parameters"":[],""returntype"":""String"",""offset"":0,""safe"":true},{""name"":""decimals"",""parameters"":[],""returntype"":""Integer"",""offset"":1,""safe"":true},{""name"":""totalSupply"",""parameters"":[],""returntype"":""Integer"",""offset"":3,""safe"":true},{""name"":""balanceOf"",""parameters"":[{""name"":""owner"",""type"":""Hash160""}],""returntype"":""Integer"",""offset"":29,""safe"":true},{""name"":""ownerOf"",""parameters"":[{""name"":""tokenId"",""type"":""ByteArray""}],""returntype"":""Hash160"",""offset"":212,""safe"":true},{""name"":""properties"",""parameters"":[{""name"":""tokenId"",""type"":""ByteArray""}],""returntype"":""Map"",""offset"":371,""safe"":true},{""name"":""tokens"",""parameters"":[],""returntype"":""InteropInterface"",""offset"":413,""safe"":true},{""name"":""tokensOf"",""parameters"":[{""name"":""owner"",""type"":""Hash160""}],""returntype"":""InteropInterface"",""offset"":441,""safe"":true},{""name"":""transfer"",""parameters"":[{""name"":""to"",""type"":""Hash160""},{""name"":""tokenId"",""type"":""ByteArray""},{""name"":""data"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":530,""safe"":false},{""name"":""testStandard"",""parameters"":[],""returntype"":""Boolean"",""offset"":831,""safe"":false},{""name"":""onNEP11Payment"",""parameters"":[{""name"":""from"",""type"":""Hash160""},{""name"":""amount"",""type"":""Integer""},{""name"":""tokenId"",""type"":""String""},{""name"":""data"",""type"":""Any""}],""returntype"":""Void"",""offset"":833,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":837,""safe"":false}],""events"":[{""name"":""Transfer"",""parameters"":[{""name"":""from"",""type"":""Hash160""},{""name"":""to"",""type"":""Hash160""},{""name"":""amount"",""type"":""Integer""},{""name"":""tokenId"",""type"":""ByteArray""}]}]},""permissions"":[{""contract"":""0x726cb6e0cd8628a1350a611384688911ab75f51b"",""methods"":[""sha256""]},{""contract"":""0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0"",""methods"":[""deserialize"",""serialize""]},{""contract"":""0xfffdc93764dbaddd97c48f252a53ea4643faa3fd"",""methods"":[""getContract""]},{""contract"":""*"",""methods"":[""onNEP11Payment""]}],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}"); + public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_SupportedStandard11Enum"",""groups"":[],""features"":{},""supportedstandards"":[""NEP-11""],""abi"":{""methods"":[{""name"":""symbol"",""parameters"":[],""returntype"":""String"",""offset"":0,""safe"":true},{""name"":""decimals"",""parameters"":[],""returntype"":""Integer"",""offset"":1,""safe"":true},{""name"":""totalSupply"",""parameters"":[],""returntype"":""Integer"",""offset"":3,""safe"":true},{""name"":""balanceOf"",""parameters"":[{""name"":""owner"",""type"":""Hash160""}],""returntype"":""Integer"",""offset"":29,""safe"":true},{""name"":""ownerOf"",""parameters"":[{""name"":""tokenId"",""type"":""ByteArray""}],""returntype"":""Hash160"",""offset"":212,""safe"":true},{""name"":""properties"",""parameters"":[{""name"":""tokenId"",""type"":""ByteArray""}],""returntype"":""Map"",""offset"":371,""safe"":true},{""name"":""tokens"",""parameters"":[],""returntype"":""InteropInterface"",""offset"":418,""safe"":true},{""name"":""tokensOf"",""parameters"":[{""name"":""owner"",""type"":""Hash160""}],""returntype"":""InteropInterface"",""offset"":446,""safe"":true},{""name"":""transfer"",""parameters"":[{""name"":""to"",""type"":""Hash160""},{""name"":""tokenId"",""type"":""ByteArray""},{""name"":""data"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":535,""safe"":false},{""name"":""testStandard"",""parameters"":[],""returntype"":""Boolean"",""offset"":836,""safe"":false},{""name"":""onNEP11Payment"",""parameters"":[{""name"":""from"",""type"":""Hash160""},{""name"":""amount"",""type"":""Integer""},{""name"":""tokenId"",""type"":""String""},{""name"":""data"",""type"":""Any""}],""returntype"":""Void"",""offset"":838,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":842,""safe"":false}],""events"":[{""name"":""Transfer"",""parameters"":[{""name"":""from"",""type"":""Hash160""},{""name"":""to"",""type"":""Hash160""},{""name"":""amount"",""type"":""Integer""},{""name"":""tokenId"",""type"":""ByteArray""}]}]},""permissions"":[{""contract"":""0x726cb6e0cd8628a1350a611384688911ab75f51b"",""methods"":[""sha256""]},{""contract"":""0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0"",""methods"":[""deserialize"",""serialize""]},{""contract"":""0xfffdc93764dbaddd97c48f252a53ea4643faa3fd"",""methods"":[""getContract""]},{""contract"":""*"",""methods"":[""onNEP11Payment""]}],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}"); /// /// Optimization: "All" /// - public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATA7znO4OTpJcbCoGp54UQN2G/OrAtkZXNlcmlhbGl6ZQEAAQ/A7znO4OTpJcbCoGp54UQN2G/OrAlzZXJpYWxpemUBAAEP/aP6Q0bqUyolj8SX3a3bZDfJ/f8LZ2V0Q29udHJhY3QBAAEPG/V1qxGJaIQTYQo1oSiGzeC2bHIGc2hhMjU2AQABDwAA/UgDQBBAWNgmFwwBAEH2tGviQZJd6DFK2CYERRBKYEBXAQF4cGgLlyYFCCINeErZKFDKABSzq6omJQwgVGhlIGFyZ3VtZW50ICJvd25lciIgaXMgaW52YWxpZC46QZv2Z84REYhOEFHQUBLAcHhowUVTi1BBkl3oMUrYJgRFENshQFcCAkGb9mfOERGIThBR0FASwHB4aMFFU4tQQZJd6DFK2CYERRDbIXFpeZ5xaRC1JgQJQGkQsyYQeGjBRVOLUEEvWMXtIg9peGjBRVOLUEHmPxiECEBXAwF4ygBAtyY8DDdUaGUgYXJndW1lbnQgInRva2VuSWQiIHNob3VsZCBiZSA2NCBvciBsZXNzIGJ5dGVzIGxvbmcuOhMRiE4QUdBBm/ZnzhLAcHhowUVTi1BBkl3oMUrYJjRFDC5UaGUgdG9rZW4gd2l0aCBnaXZlbiAidG9rZW5JZCIgZG9lcyBub3QgZXhpc3QuOnFpNwAAcmoQzkBXAgETEYhOEFHQQZv2Z84SwHB4aMFFU4tQQZJd6DE3AABxyGkRzktT0EBXAQATEYhOEFHQQZv2Z84SwHATaMFFQd8wuJpAVwEBeHBoC5cmBQgiDXhK2ShQygAUs6uqJiQMH1RoZSBhcmd1bWVudCAib3duZXIiIGlzIGludmFsaWQ6FBGIThBR0EGb9mfOEsBwE3howUVTi1BB3zC4mkBXAwN4cGgLlyYFCCINeErZKFDKABSzq6omIgwdVGhlIGFyZ3VtZW50ICJ0byIgaXMgaW52YWxpZC46ExGIThBR0EGb9mfOEsBweWjBRVOLUEGSXegxNwAAcWkQznJqQfgn7IyqJgQJQGp4mCYleEppEFHQRWk3AQBKeWjBRVOLUEHmPxiERQ95ajQPEXl4NAp6eXhqNEUIQFcCA3p4NdD9//9FQZv2Z84UEYhOEFHQUBLAcHh5i9socXoQtyYQEGlowUVTi1BB5j8YhEBpaMFFU4tQQS9Yxe1AVwEEwkp4z0p5z0oRz0p6zwwIVHJhbnNmZXJBlQFvYXlwaAuXqiQFCSILeTcCAHBoC5eqJiB7ehF4FMAfDA5vbk5FUDExUGF5bWVudHlBYn1bUkVACEBXAARAVgFAmmgU6Q==")); + public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATA7znO4OTpJcbCoGp54UQN2G/OrAtkZXNlcmlhbGl6ZQEAAQ/A7znO4OTpJcbCoGp54UQN2G/OrAlzZXJpYWxpemUBAAEP/aP6Q0bqUyolj8SX3a3bZDfJ/f8LZ2V0Q29udHJhY3QBAAEPG/V1qxGJaIQTYQo1oSiGzeC2bHIGc2hhMjU2AQABDwAA/U0DQBBAWNgmFwwBAEH2tGviQZJd6DFK2CYERRBKYEBXAQF4cGgLlyYFCCINeErZKFDKABSzq6omJQwgVGhlIGFyZ3VtZW50ICJvd25lciIgaXMgaW52YWxpZC46QZv2Z84REYhOEFHQUBLAcHhowUVTi1BBkl3oMUrYJgRFENshQFcCAkGb9mfOERGIThBR0FASwHB4aMFFU4tQQZJd6DFK2CYERRDbIXFpeZ5xaRC1JgQJQGkQsyYQeGjBRVOLUEEvWMXtIg9peGjBRVOLUEHmPxiECEBXAwF4ygBAtyY8DDdUaGUgYXJndW1lbnQgInRva2VuSWQiIHNob3VsZCBiZSA2NCBvciBsZXNzIGJ5dGVzIGxvbmcuOhMRiE4QUdBBm/ZnzhLAcHhowUVTi1BBkl3oMUrYJjRFDC5UaGUgdG9rZW4gd2l0aCBnaXZlbiAidG9rZW5JZCIgZG9lcyBub3QgZXhpc3QuOnFpNwAAcmoQzkBXAgETEYhOEFHQQZv2Z84SwHB4aMFFU4tQQZJd6DE3AABxyEoMBG5hbWVpEc7QQFcBABMRiE4QUdBBm/ZnzhLAcBNowUVB3zC4mkBXAQF4cGgLlyYFCCINeErZKFDKABSzq6omJAwfVGhlIGFyZ3VtZW50ICJvd25lciIgaXMgaW52YWxpZDoUEYhOEFHQQZv2Z84SwHATeGjBRVOLUEHfMLiaQFcDA3hwaAuXJgUIIg14StkoUMoAFLOrqiYiDB1UaGUgYXJndW1lbnQgInRvIiBpcyBpbnZhbGlkLjoTEYhOEFHQQZv2Z84SwHB5aMFFU4tQQZJd6DE3AABxaRDOcmpB+CfsjKomBAlAaniYJiV4SmkQUdBFaTcBAEp5aMFFU4tQQeY/GIRFD3lqNA8ReXg0Cnp5eGo0RQhAVwIDeng1y/3//0VBm/ZnzhQRiE4QUdBQEsBweHmL2yhxehC3JhAQaWjBRVOLUEHmPxiEQGlowUVTi1BBL1jF7UBXAQTCSnjPSnnPShHPSnrPDAhUcmFuc2ZlckGVAW9heXBoC5eqJAUJIgt5NwIAcGgLl6omIHt6EXgUwB8MDm9uTkVQMTFQYXltZW50eUFifVtSRUAIQFcABEBWAUDXxctQ")); #endregion