Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cover tests #1277

Merged
merged 9 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,15 @@ private void EmitComplexAssignmentOperator(ITypeSymbol type, SyntaxToken operato
"%=" => (OpCode.MOD, true),
"&=" => isBoolean ? (OpCode.BOOLAND, false) : (OpCode.AND, true),
"^=" when !isBoolean => (OpCode.XOR, true),
"^=" when isBoolean => (OpCode.XOR, false),
"|=" => isBoolean ? (OpCode.BOOLOR, false) : (OpCode.OR, true),
"<<=" => (OpCode.SHL, true),
">>=" => (OpCode.SHR, true),
_ => throw new CompilationException(operatorToken, DiagnosticId.SyntaxNotSupported, $"Unsupported operator: {operatorToken}")
};
AddInstruction(opcode);
if (opcode == OpCode.XOR && isBoolean)
ChangeType(VM.Types.StackItemType.Boolean);
if (isString) ChangeType(VM.Types.StackItemType.ByteString);
if (checkResult) EnsureIntegerInRange(type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ private static byte[] ConvertToECPoint(string strValue)
private void EnsureIntegerInRange(ITypeSymbol type)
{
if (type.Name == "BigInteger") return;
while (type.NullableAnnotation == NullableAnnotation.Annotated)
// Supporting nullable integer like `byte?`
type = ((INamedTypeSymbol)type).TypeArguments.First();
var (minValue, maxValue, mask) = type.Name switch
{
"SByte" => ((BigInteger)sbyte.MinValue, (BigInteger)sbyte.MaxValue, (BigInteger)0xff),
Expand All @@ -276,6 +279,7 @@ private void EnsureIntegerInRange(ITypeSymbol type)
"UInt16" => (ushort.MinValue, ushort.MaxValue, 0xffff),
"UInt32" => (uint.MinValue, uint.MaxValue, 0xffffffff),
"UInt64" => (ulong.MinValue, ulong.MaxValue, 0xffffffffffffffff),
//"Boolean" => (0, 1, 0x01),
_ => throw new CompilationException(DiagnosticId.SyntaxNotSupported, $"Unsupported type: {type}")
};
JumpTarget checkUpperBoundTarget = new(), adjustTarget = new(), endTarget = new();
Expand Down
33 changes: 30 additions & 3 deletions tests/Neo.Compiler.CSharp.TestContracts/Contract_MemberAccess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,51 @@ public static void TestMain()
//Runtime.Log(MyClass.Data3.ToString());
Runtime.Log(my.Data4);
Runtime.Log(my.Method());
}

public static void TestComplexAssignment()
{
var my = new MyClass();
ExecutionEngine.Assert(my.PropertyComplexAssignment() == -1);
ExecutionEngine.Assert((my.Data1 /= -1) == 1);
ExecutionEngine.Assert(my.FieldComplexAssignment() == 0);
ExecutionEngine.Assert(my.FieldComplexAssignmentString() == "hello2");
ExecutionEngine.Assert((my.Data4 += "33") == "hello233");
}

public static void TestStaticComplexAssignment()
{
MyClass.Data3 = 0;
ExecutionEngine.Assert(MyClass.Data3 == 0);
MyClass.Data3 += 1;
ExecutionEngine.Assert(MyClass.Data3 == 1);

ExecutionEngine.Assert(MyClass.Data6 == false);
MyClass.Data6 |= true;
ExecutionEngine.Assert(MyClass.Data6 == true);
MyClass.Data6 ^= true;
ExecutionEngine.Assert(MyClass.Data6 == false);
}

public class MyClass
{
public int Data1 { get; set; }
public int Data1 { get; set; } // non-static IPropertySymbol

public const string Data2 = "msg";

public static int Data3 = 3;
public static int Data3 = 3; // static IFieldSymbol

public string Data4 = "hello"; // non-static IFieldSymbol

public string Data4 = "hello";
public int Data5 = 5; // non-static IFieldSymbol

public static bool Data6 { get; set; } = false; // static IPropertySymbol

public string Method() => "";

public int PropertyComplexAssignment() => Data1 -= 1;
public int FieldComplexAssignment() => Data5 ^= Data5;
public string FieldComplexAssignmentString() => Data4 += "2";
}
}
}
48 changes: 38 additions & 10 deletions tests/Neo.Compiler.CSharp.TestContracts/Contract_NULL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,13 @@ public void VoidMethod()
{
}
public int IntProperty => 42;
public byte? NullableProperty;
public byte? NullableField;
public byte?[]? NullableArray { get; set; }
public static bool? StaticNullableField = true;
public static int? StaticNullableProperty { get; set; } = 0;

public byte? FieldCoalesce(byte? f) => NullableField ??= f;
public byte?[]? PropertyCoalesce(byte?[]? p) => NullableArray ??= p;
}

public static void NullType()
Expand All @@ -106,21 +111,44 @@ public static void NullType()
obj1?.VoidMethod();
}

public static void NullCoalescingAssignment()
public static void NullCoalescingAssignment(byte? nullableArg)
{
TestClass t = new() { NullableProperty = 1 };
ExecutionEngine.Assert(t.NullableProperty == 1);
t.NullableProperty = null;
nullableArg ??= 1;
TestClass t = new() { NullableField = nullableArg };
ExecutionEngine.Assert(t.NullableField == 1);
t.NullableField = null;
ExecutionEngine.Assert(t.NullableArray == null);
t.NullableArray ??= [0, null, 2, 3, t.NullableProperty];
t.NullableProperty ??= t.NullableArray[0];
ExecutionEngine.Assert(t.NullableProperty == 0);
t.NullableProperty ??= t.NullableArray[1];
ExecutionEngine.Assert(t.NullableProperty == 0);
t.NullableArray ??= [0, null, 2, 3, t.NullableField];
t.PropertyCoalesce([null]);
t.FieldCoalesce(t.NullableArray![0]);
ExecutionEngine.Assert(t.NullableField == 0);
t.NullableField ??= t.NullableArray[1];
ExecutionEngine.Assert(t.NullableField == 0);
t.NullableArray[1] ??= 1;
ExecutionEngine.Assert(t.NullableArray[1] == 1);
t.NullableArray[1] ??= 2;
ExecutionEngine.Assert(t.NullableArray[1] == 1);
t.NullableArray[1]++;
ExecutionEngine.Assert(t.NullableArray[1] == 2);
t.NullableArray = [null];
ExecutionEngine.Assert(t.NullableArray[0] == null);
}

public static void StaticNullableCoalesceAssignment()
{
TestClass.StaticNullableField ??= null;
ExecutionEngine.Assert(TestClass.StaticNullableField == true);
TestClass.StaticNullableField = null;
ExecutionEngine.Assert((TestClass.StaticNullableField ??= false) == false);

TestClass.StaticNullableProperty ??= null;
ExecutionEngine.Assert(TestClass.StaticNullableProperty == 0);
TestClass.StaticNullableProperty = null;
ExecutionEngine.Assert((TestClass.StaticNullableProperty ??= 1) == 1);
TestClass.StaticNullableProperty++;
ExecutionEngine.Assert(TestClass.StaticNullableProperty == 2);
--TestClass.StaticNullableProperty;
ExecutionEngine.Assert(TestClass.StaticNullableProperty == 1);
}
}
}
20 changes: 17 additions & 3 deletions tests/Neo.Compiler.CSharp.TestContracts/Contract_PostfixUnary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,21 @@ public class Person
{
public string Name { get; set; }

public int Age;
public int Age = 1;
public int Gender { get; set; } = 0;

public int[] BWH { get; set; } = { 80, 60, 80 };

public Person(string name) { Name = name; }
public static int Height = 170;
public static int Weight { get; set; } = 50;

public static void Invert()
{
ExecutionEngine.Assert(~(Height++) == -171);
ExecutionEngine.Assert(~(--Weight) == -50);
}

public Person(string name) { Name = name; Age--; ++Age; --Age; }
}

public static string? Test()
Expand Down Expand Up @@ -50,11 +60,15 @@ public static void TestUndefinedCase()
ExecutionEngine.Assert(p.BWH[0] == 80);
p.BWH[0] = ++p.BWH[0];
ExecutionEngine.Assert(p.BWH[0] == 81);

ExecutionEngine.Assert(p.Gender++ == 0);
}

public static void TestInvert()
{
ExecutionEngine.Assert(~1 == -2);
Person.Invert();
ExecutionEngine.Assert(~(Person.Height--) == -172);
ExecutionEngine.Assert(~(++Person.Height) == -172);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ public abstract class Contract_MemberAccess(Neo.SmartContract.Testing.SmartContr
{
#region Compiled data

public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_MemberAccess"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""testMain"",""parameters"":[],""returntype"":""Void"",""offset"":0,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":118,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0"",""methods"":[""itoa""]}],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}");
public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_MemberAccess"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""testMain"",""parameters"":[],""returntype"":""Void"",""offset"":0,""safe"":false},{""name"":""testComplexAssignment"",""parameters"":[],""returntype"":""Void"",""offset"":59,""safe"":false},{""name"":""testStaticComplexAssignment"",""parameters"":[],""returntype"":""Void"",""offset"":331,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":414,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0"",""methods"":[""itoa""]}],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}");

/// <summary>
/// Optimization: "All"
/// </summary>
public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable<Neo.SmartContract.NefFile>(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHA7znO4OTpJcbCoGp54UQN2G/OrARpdG9hAQABDwAAe1cBAAwFaGVsbG8QEsBwaBDONwAAQc/nR5YMA21zZ0HP50eWaBHOQc/nR5ZoNERBz+dHlhBgWBCXOVgRnkoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9gWBGXOUBXAAEMAEBWARNgQLlKFjs="));
public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable<Neo.SmartContract.NefFile>(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHA7znO4OTpJcbCoGp54UQN2G/OrARpdG9hAQABDwAA/aUBVwEAFQwFaGVsbG8QE8BwaBDONwAAQc/nR5YMA21zZ0HP50eWaBHOQc/nR5ZoNAhBz+dHlkBXAAEMAEBXAQAVDAVoZWxsbxATwHBoNHMPlzloShDOD6FKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfTlAQUdARlzloNG4QlzloNaYAAAAMBmhlbGxvMpc5aEoRzgwCMzOL2yhOEVDQDAhoZWxsbzIzM5c5QFcAAXhKEM4Rn0oCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9OUBBR0EBXAAF4ShLOeBLOk0oCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9OElDQQFcAAXhKEc4MATKL2yhOEVDQQBBgWBCXOVgRnkoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9gWBGXOVkJlzlZCKxhWQiXOVkIk9sgYVkJlzlAVgITYAlhQFa5l84="));

#endregion

Expand All @@ -25,11 +25,86 @@ public abstract class Contract_MemberAccess(Neo.SmartContract.Testing.SmartContr
/// Unsafe method
/// </summary>
/// <remarks>
/// Script: VwEADAVoZWxsbxASwHBoEM43AABBz+dHlgwDbXNnQc/nR5ZoEc5Bz+dHlmg0REHP50eWEGBYEJc5WBGeSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn2BYEZc5QA==
/// Script: VwEAFQwFaGVsbG8QE8BwaDRzD5c5aEoQzg+hSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn05QEFHQEZc5aDRuEJc5aDWmAAAADAZoZWxsbzKXOWhKEc4MAjMzi9soThFQ0AwIaGVsbG8yMzOXOUA=
/// INITSLOT 0100 [64 datoshi]
/// PUSH5 [1 datoshi]
/// PUSHDATA1 68656C6C6F 'hello' [8 datoshi]
/// PUSH0 [1 datoshi]
/// PUSH2 [1 datoshi]
/// PUSH3 [1 datoshi]
/// PACK [2048 datoshi]
/// STLOC0 [2 datoshi]
/// LDLOC0 [2 datoshi]
/// CALL 73 [512 datoshi]
/// PUSHM1 [1 datoshi]
/// EQUAL [32 datoshi]
/// ASSERT [1 datoshi]
/// LDLOC0 [2 datoshi]
/// DUP [2 datoshi]
/// PUSH0 [1 datoshi]
/// PICKITEM [64 datoshi]
/// PUSHM1 [1 datoshi]
/// DIV [8 datoshi]
/// DUP [2 datoshi]
/// PUSHINT32 00000080 [1 datoshi]
/// JMPGE 04 [2 datoshi]
/// JMP 0A [2 datoshi]
/// DUP [2 datoshi]
/// PUSHINT32 FFFFFF7F [1 datoshi]
/// JMPLE 1E [2 datoshi]
/// PUSHINT64 FFFFFFFF00000000 [1 datoshi]
/// AND [8 datoshi]
/// DUP [2 datoshi]
/// PUSHINT32 FFFFFF7F [1 datoshi]
/// JMPLE 0C [2 datoshi]
/// PUSHINT64 0000000001000000 [1 datoshi]
/// SUB [8 datoshi]
/// TUCK [2 datoshi]
/// SWAP [2 datoshi]
/// PUSH0 [1 datoshi]
/// ROT [2 datoshi]
/// SETITEM [8192 datoshi]
/// PUSH1 [1 datoshi]
/// EQUAL [32 datoshi]
/// ASSERT [1 datoshi]
/// LDLOC0 [2 datoshi]
/// CALL 6E [512 datoshi]
/// PUSH0 [1 datoshi]
/// EQUAL [32 datoshi]
/// ASSERT [1 datoshi]
/// LDLOC0 [2 datoshi]
/// CALL_L A6000000 [512 datoshi]
/// PUSHDATA1 68656C6C6F32 'hello2' [8 datoshi]
/// EQUAL [32 datoshi]
/// ASSERT [1 datoshi]
/// LDLOC0 [2 datoshi]
/// DUP [2 datoshi]
/// PUSH1 [1 datoshi]
/// PICKITEM [64 datoshi]
/// PUSHDATA1 3333 '33' [8 datoshi]
/// CAT [2048 datoshi]
/// CONVERT 28 'ByteString' [8192 datoshi]
/// TUCK [2 datoshi]
/// PUSH1 [1 datoshi]
/// SWAP [2 datoshi]
/// SETITEM [8192 datoshi]
/// PUSHDATA1 68656C6C6F323333 'hello233' [8 datoshi]
/// EQUAL [32 datoshi]
/// ASSERT [1 datoshi]
/// RET [0 datoshi]
/// </remarks>
[DisplayName("testComplexAssignment")]
public abstract void TestComplexAssignment();

/// <summary>
/// Unsafe method
/// </summary>
/// <remarks>
/// Script: VwEAFQwFaGVsbG8QE8BwaBDONwAAQc/nR5YMA21zZ0HP50eWaBHOQc/nR5ZoNAhBz+dHlkA=
/// INITSLOT 0100 [64 datoshi]
/// PUSH5 [1 datoshi]
/// PUSHDATA1 68656C6C6F 'hello' [8 datoshi]
/// PUSH0 [1 datoshi]
/// PUSH3 [1 datoshi]
/// PACK [2048 datoshi]
/// STLOC0 [2 datoshi]
/// LDLOC0 [2 datoshi]
Expand All @@ -44,8 +119,18 @@ public abstract class Contract_MemberAccess(Neo.SmartContract.Testing.SmartContr
/// PICKITEM [64 datoshi]
/// SYSCALL CFE74796 'System.Runtime.Log' [32768 datoshi]
/// LDLOC0 [2 datoshi]
/// CALL 44 [512 datoshi]
/// CALL 08 [512 datoshi]
/// SYSCALL CFE74796 'System.Runtime.Log' [32768 datoshi]
/// RET [0 datoshi]
/// </remarks>
[DisplayName("testMain")]
public abstract void TestMain();

/// <summary>
/// Unsafe method
/// </summary>
/// <remarks>
/// Script: EGBYEJc5WBGeSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn2BYEZc5WQmXOVkIrGFZCJc5WQiT2yBhWQmXOUA=
/// PUSH0 [1 datoshi]
/// STSFLD0 [2 datoshi]
/// LDSFLD0 [2 datoshi]
Expand Down Expand Up @@ -74,10 +159,31 @@ public abstract class Contract_MemberAccess(Neo.SmartContract.Testing.SmartContr
/// PUSH1 [1 datoshi]
/// EQUAL [32 datoshi]
/// ASSERT [1 datoshi]
/// LDSFLD1 [2 datoshi]
/// PUSHF [1 datoshi]
/// EQUAL [32 datoshi]
/// ASSERT [1 datoshi]
/// LDSFLD1 [2 datoshi]
/// PUSHT [1 datoshi]
/// BOOLOR [8 datoshi]
/// STSFLD1 [2 datoshi]
/// LDSFLD1 [2 datoshi]
/// PUSHT [1 datoshi]
/// EQUAL [32 datoshi]
/// ASSERT [1 datoshi]
/// LDSFLD1 [2 datoshi]
/// PUSHT [1 datoshi]
/// XOR [8 datoshi]
/// CONVERT 20 'Boolean' [8192 datoshi]
/// STSFLD1 [2 datoshi]
/// LDSFLD1 [2 datoshi]
/// PUSHF [1 datoshi]
/// EQUAL [32 datoshi]
/// ASSERT [1 datoshi]
/// RET [0 datoshi]
/// </remarks>
[DisplayName("testMain")]
public abstract void TestMain();
[DisplayName("testStaticComplexAssignment")]
public abstract void TestStaticComplexAssignment();

#endregion
}
Loading
Loading