mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-27 20:18:01 +02:00
Initial checkin
This commit is contained in:
parent
c74712dad9
commit
078564ac9e
3242 changed files with 1616395 additions and 0 deletions
115
IDEHelper/Tests/src/Append.bf
Normal file
115
IDEHelper/Tests/src/Append.bf
Normal file
|
@ -0,0 +1,115 @@
|
|||
#pragma warning disable 168
|
||||
|
||||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Append
|
||||
{
|
||||
class ClassA
|
||||
{
|
||||
int32 mA = 0x11223344;
|
||||
|
||||
[AllowAppend]
|
||||
public this()
|
||||
{
|
||||
uint8* ptr = append uint8[3]*;
|
||||
ptr[0] = 0x55;
|
||||
ptr[1] = 0x66;
|
||||
ptr[2] = 0x77;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassB
|
||||
{
|
||||
[AllowAppend]
|
||||
public this(int16 i, int32 j)
|
||||
{
|
||||
uint8* ptr = append uint8[i]*;
|
||||
for (int k < i)
|
||||
ptr[k] = (uint8)(0xA0 | k);
|
||||
}
|
||||
}
|
||||
|
||||
class ClassC : ClassB
|
||||
{
|
||||
public static int sCallCount;
|
||||
|
||||
static int GetIntVal()
|
||||
{
|
||||
sCallCount++;
|
||||
return 123;
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
public this(int16 i) : base(i, (int32)GetIntVal())
|
||||
{
|
||||
uint32* val = append uint32[2]*;
|
||||
val[0] = 0x11223344;
|
||||
val[1] = 0x55667788;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassD
|
||||
{
|
||||
int16 mA = 0x1122;
|
||||
|
||||
[AllowAppend]
|
||||
public this()
|
||||
{
|
||||
uint32* val = append uint32[1]*;
|
||||
uint8* val2 = append uint8[1]*;
|
||||
val[0] = 0x33445566;
|
||||
//Foof();
|
||||
|
||||
val2[0] = 0xBB;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassE : ClassD
|
||||
{
|
||||
[AllowAppend]
|
||||
public this()
|
||||
{
|
||||
uint64* val = append uint64[1]*;
|
||||
val[0] = 0x1020304050607080L;
|
||||
}
|
||||
}
|
||||
|
||||
static void CheckData(Object obj, int lastAllocSize, uint8[] data)
|
||||
{
|
||||
int objSize = typeof(Object).InstanceSize;
|
||||
Test.Assert(lastAllocSize == data.Count + objSize);
|
||||
uint8* ptr = (uint8*)Internal.UnsafeCastToPtr(obj) + objSize;
|
||||
for (int i < data.Count)
|
||||
Test.Assert(ptr[i] == data[i]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void Test()
|
||||
{
|
||||
TrackedAlloc trackedAlloc = scope .();
|
||||
|
||||
int objSize = typeof(Object).InstanceSize;
|
||||
|
||||
let ca = new:trackedAlloc ClassA();
|
||||
CheckData(ca, trackedAlloc.mLastAllocSize, scope .(
|
||||
0x44, 0x33, 0x22, 0x11, 0x55, 0x66, 0x77));
|
||||
delete:trackedAlloc ca;
|
||||
|
||||
let cc = new:trackedAlloc ClassC(10);
|
||||
Test.Assert(ClassC.sCallCount == 1); // This ensures we had a constant evaluation of the size
|
||||
CheckData(cc, trackedAlloc.mLastAllocSize, scope .(
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0x00, 0x00, 0x44, 0x33, 0x22, 0x11,
|
||||
0x88, 0x77, 0x66, 0x55));
|
||||
delete:trackedAlloc cc;
|
||||
|
||||
let ce = new:trackedAlloc ClassE();
|
||||
CheckData(cc, trackedAlloc.mLastAllocSize, scope .(
|
||||
0x22, 0x11, 0x00, 0x00, 0x66, 0x55, 0x44, 0x33, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10
|
||||
));
|
||||
delete:trackedAlloc ce;
|
||||
}
|
||||
}
|
||||
}
|
40
IDEHelper/Tests/src/Boxing.bf
Normal file
40
IDEHelper/Tests/src/Boxing.bf
Normal file
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Boxing
|
||||
{
|
||||
interface IFace
|
||||
{
|
||||
int Get() mut;
|
||||
}
|
||||
|
||||
struct Struct : IFace
|
||||
{
|
||||
public int mA = 100;
|
||||
public int mB = 200;
|
||||
|
||||
public int Get() mut
|
||||
{
|
||||
mA += 1000;
|
||||
return mA;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
Struct val0 = .();
|
||||
Object obj0 = val0;
|
||||
IFace iface0 = (IFace)obj0;
|
||||
Test.Assert(iface0.Get() == 1100);
|
||||
Test.Assert(val0.mA == 100); // This should copy values
|
||||
|
||||
/*Struct val1 = .();
|
||||
Object obj1 = (Object)(ref val1);
|
||||
IFace iface1 = (IFace)obj1;
|
||||
Test.Assert(iface1.Get() == 1100);
|
||||
Test.Assert(val1.mA == 1100); // This should reference values*/
|
||||
}
|
||||
}
|
||||
}
|
94
IDEHelper/Tests/src/Delegates.bf
Normal file
94
IDEHelper/Tests/src/Delegates.bf
Normal file
|
@ -0,0 +1,94 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Delegates
|
||||
{
|
||||
struct Valueless
|
||||
{
|
||||
public int MutMethod(int a) mut
|
||||
{
|
||||
return 210 + a;
|
||||
}
|
||||
|
||||
public int NonMutMethod(int a)
|
||||
{
|
||||
return 210 + a;
|
||||
}
|
||||
}
|
||||
|
||||
struct Splattable
|
||||
{
|
||||
public int32 mA = 10;
|
||||
public int16 mB = 200;
|
||||
|
||||
public int MutMethod(int a) mut
|
||||
{
|
||||
mB += 100;
|
||||
return mA + mB + a;
|
||||
}
|
||||
|
||||
public int NonMutMethod(int a)
|
||||
{
|
||||
return mA + mB + a;
|
||||
}
|
||||
}
|
||||
|
||||
struct NonSplattable
|
||||
{
|
||||
public int32 mA = 10;
|
||||
public int16 mB = 200;
|
||||
public int64 mC = 300;
|
||||
public int64 mD = 400;
|
||||
|
||||
public int MutMethod(int a) mut
|
||||
{
|
||||
mB += 100;
|
||||
return mA + mB + a;
|
||||
}
|
||||
|
||||
public int NonMutMethod(int a)
|
||||
{
|
||||
return mA + mB + a;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
delegate int(int a) dlg;
|
||||
|
||||
Valueless val0 = .();
|
||||
dlg = scope => val0.MutMethod;
|
||||
Test.Assert(dlg(9) == 219);
|
||||
dlg = scope => val0.NonMutMethod;
|
||||
Test.Assert(dlg(9) == 219);
|
||||
|
||||
Splattable val1 = .();
|
||||
dlg = scope => val1.MutMethod;
|
||||
Test.Assert(dlg(9) == 319);
|
||||
dlg = scope => val1.NonMutMethod;
|
||||
Test.Assert(dlg(9) == 219);
|
||||
Test.Assert(val1.mB == 200);
|
||||
|
||||
dlg = scope => (ref val1).MutMethod;
|
||||
Test.Assert(dlg(9) == 319);
|
||||
dlg = scope => (ref val1).NonMutMethod;
|
||||
Test.Assert(dlg(9) == 319);
|
||||
Test.Assert(val1.mB == 300);
|
||||
|
||||
NonSplattable val2 = .();
|
||||
dlg = scope => val2.MutMethod;
|
||||
Test.Assert(dlg(9) == 319);
|
||||
dlg = scope => val2.NonMutMethod;
|
||||
Test.Assert(dlg(9) == 219);
|
||||
Test.Assert(val2.mB == 200);
|
||||
|
||||
dlg = scope => (ref val2).MutMethod;
|
||||
Test.Assert(dlg(9) == 319);
|
||||
dlg = scope => (ref val2).NonMutMethod;
|
||||
Test.Assert(dlg(9) == 319);
|
||||
Test.Assert(val2.mB == 300);
|
||||
}
|
||||
}
|
||||
}
|
118
IDEHelper/Tests/src/Enums.bf
Normal file
118
IDEHelper/Tests/src/Enums.bf
Normal file
|
@ -0,0 +1,118 @@
|
|||
#pragma warning disable 168
|
||||
|
||||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Enums
|
||||
{
|
||||
enum EnumA
|
||||
{
|
||||
A,
|
||||
B
|
||||
}
|
||||
|
||||
enum EnumB
|
||||
{
|
||||
A,
|
||||
B = 600
|
||||
}
|
||||
|
||||
enum EnumC
|
||||
{
|
||||
A,
|
||||
B = 0x7FFFFFFF
|
||||
}
|
||||
|
||||
enum EnumD
|
||||
{
|
||||
A,
|
||||
B = 0x7FFFFFFFFFFFFFFFL
|
||||
}
|
||||
|
||||
enum EnumE
|
||||
{
|
||||
case A;
|
||||
case B(int a);
|
||||
case C(int a, int b);
|
||||
}
|
||||
|
||||
enum EnumF
|
||||
{
|
||||
case None;
|
||||
case EE(EnumE ee);
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestBasic()
|
||||
{
|
||||
EnumA ea = .A;
|
||||
Test.Assert((int)ea == 0);
|
||||
Test.Assert(sizeof(EnumA) == 1);
|
||||
Test.Assert(sizeof(EnumB) == 2);
|
||||
Test.Assert(sizeof(EnumC) == 4);
|
||||
Test.Assert(sizeof(EnumD) == 8);
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestPayloads()
|
||||
{
|
||||
Test.Assert(sizeof(EnumE) == sizeof(int)*2 + 1);
|
||||
Test.Assert(sizeof(EnumF) == sizeof(int)*2 + 1 + 1);
|
||||
|
||||
EnumE ee = .C(1, 2);
|
||||
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
switch (ee)
|
||||
{
|
||||
case .A:
|
||||
case .B(out a):
|
||||
case .C(out a, out b):
|
||||
}
|
||||
Test.Assert(a == 1);
|
||||
Test.Assert(b == 2);
|
||||
|
||||
EnumF ef = .EE(.C(3, 4));
|
||||
switch (ef)
|
||||
{
|
||||
case .EE(let eeVal):
|
||||
if (!(eeVal case .C(out a, out b)))
|
||||
{
|
||||
Test.FatalError();
|
||||
}
|
||||
default:
|
||||
}
|
||||
Test.Assert(a == 3);
|
||||
Test.Assert(b == 4);
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestCases()
|
||||
{
|
||||
EnumE ee = .A;
|
||||
|
||||
int val = 123;
|
||||
bool matches = ee case .B(out val);
|
||||
Test.Assert(val == 0);
|
||||
|
||||
// We only assign to 'val' on true here
|
||||
val = 123;
|
||||
if (ee case .B(out val))
|
||||
{
|
||||
Test.Assert(val == 0 );
|
||||
}
|
||||
Test.Assert(val == 123);
|
||||
|
||||
// We always assign to 'val' here because we may enter even if there's no match
|
||||
val = 123;
|
||||
if ((ee case .B(out val)) || (val > 0))
|
||||
{
|
||||
}
|
||||
Test.Assert(val == 0);
|
||||
|
||||
ee = .B(10);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
174
IDEHelper/Tests/src/Extensions.bf
Normal file
174
IDEHelper/Tests/src/Extensions.bf
Normal file
|
@ -0,0 +1,174 @@
|
|||
using System;
|
||||
|
||||
namespace System.Collections.Generic
|
||||
{
|
||||
extension List<T> where T : Tests.Extensions.IGetExVal
|
||||
{
|
||||
public int GetExVals()
|
||||
{
|
||||
int total = 0;
|
||||
for (var val in this)
|
||||
{
|
||||
total += val.GetExVal();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace System.Collections.Generic
|
||||
{
|
||||
extension TClass<T>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Extensions
|
||||
{
|
||||
public interface IGetExVal
|
||||
{
|
||||
int GetExVal();
|
||||
}
|
||||
|
||||
class ClassA
|
||||
{
|
||||
public int32 mA;
|
||||
}
|
||||
|
||||
extension ClassA
|
||||
{
|
||||
public int32 mB;
|
||||
}
|
||||
|
||||
class TClassA<T> where T : IDisposable
|
||||
{
|
||||
public int32 mA = 10;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
mA += 20;
|
||||
}
|
||||
|
||||
public int GetB()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
extension TClassA<T> where T : IGetExVal
|
||||
{
|
||||
public T mTVal;
|
||||
|
||||
public T GetIt()
|
||||
{
|
||||
return mTVal;
|
||||
}
|
||||
|
||||
public int GetB()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
class ImpGetExVal : IGetExVal, IDisposable
|
||||
{
|
||||
public int32 mVal = 999;
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int IGetExVal.GetExVal()
|
||||
{
|
||||
return mVal;
|
||||
}
|
||||
}
|
||||
|
||||
class ImpDisp : IDisposable
|
||||
{
|
||||
public int32 mVal = 999;
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int UseTClass<T>(TClassA<T> val) where T : IDisposable
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int UseTClass<T>(TClassA<T> val) where T : IDisposable, IGetExVal
|
||||
{
|
||||
return val.GetIt().GetExVal();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
Test.Assert(typeof(ClassA).InstanceSize == typeof(Object).InstanceSize + 4+4);
|
||||
|
||||
ClassA ca = scope ClassA();
|
||||
ca.mA = 123;
|
||||
ca.mB = 234;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestTClass()
|
||||
{
|
||||
TClassA<ImpGetExVal> ta = scope TClassA<ImpGetExVal>();
|
||||
ta.mTVal = scope ImpGetExVal();
|
||||
int val = ta.GetIt().mVal;
|
||||
Test.Assert(val == 999);
|
||||
Test.Assert(typeof(decltype(ta)).InstanceSize == typeof(Object).InstanceSize + 4 + sizeof(Object));
|
||||
Test.Assert(UseTClass(ta) == 999);
|
||||
Test.Assert(ta.GetB() == 2);
|
||||
|
||||
TClassA<ImpDisp> tb = scope TClassA<ImpDisp>();
|
||||
Test.Assert(typeof(decltype(tb)).InstanceSize == typeof(Object).InstanceSize + 4);
|
||||
Test.Assert(UseTClass(tb) == -1);
|
||||
Test.Assert(tb.GetB() == 1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestList()
|
||||
{
|
||||
System.Collections.Generic.List<ImpGetExVal> list = scope .();
|
||||
|
||||
ImpGetExVal val0 = scope ImpGetExVal();
|
||||
list.Add(val0);
|
||||
val0.mVal = 10;
|
||||
ImpGetExVal val1 = scope ImpGetExVal();
|
||||
list.Add(val1);
|
||||
val1.mVal = 100;
|
||||
|
||||
int val = list.GetExVals();
|
||||
Test.Assert(val == 110);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestSharedData()
|
||||
{
|
||||
LibClassA ca = scope LibClassA();
|
||||
Test.Assert(ca.mA == 7);
|
||||
Test.Assert(ca.LibB_GetB() == 108);
|
||||
Test.Assert(ca.LibC_GetB() == 13);
|
||||
Test.Assert(ca.GetVal2() == 9);
|
||||
|
||||
ca = scope LibClassA(12345);
|
||||
Test.Assert(ca.mA == 7);
|
||||
Test.Assert(ca.LibB_GetB() == 1008);
|
||||
Test.Assert(ca.LibC_GetB() == 13);
|
||||
|
||||
ca = scope LibClassA((int8)2);
|
||||
Test.Assert(ca.mA == 7);
|
||||
Test.Assert(ca.LibB_GetB() == 8);
|
||||
Test.Assert(ca.LibC_GetB() == 30013);
|
||||
}
|
||||
}
|
||||
}
|
397
IDEHelper/Tests/src/FuncRefs.bf
Normal file
397
IDEHelper/Tests/src/FuncRefs.bf
Normal file
|
@ -0,0 +1,397 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class FuncRefs2
|
||||
{
|
||||
public static int Do10Ext<T>(T func, int val) where T : delegate int(int a)
|
||||
{
|
||||
int total = 0;
|
||||
for (int i < 10)
|
||||
total += func(val);
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
class FuncRefs
|
||||
{
|
||||
static int FuncA(int val)
|
||||
{
|
||||
return val * 10;
|
||||
}
|
||||
|
||||
static float FuncA(float val)
|
||||
{
|
||||
return val * -10;
|
||||
}
|
||||
|
||||
static int Do10<T>(T func, int val) where T : delegate int(int a)
|
||||
{
|
||||
int total = 0;
|
||||
for (int i < 5)
|
||||
total += func(val);
|
||||
|
||||
delegate int(int a) dlg = scope => func;
|
||||
for (int i < 5)
|
||||
total += dlg(val);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
static float Do10f<T>(T func, float val) where T : delegate float(float a)
|
||||
{
|
||||
float total = 0;
|
||||
for (int i < 10)
|
||||
total += func(val);
|
||||
return total;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
int val0 = Do10(scope => FuncA, 3);
|
||||
Test.Assert(val0 == 300);
|
||||
|
||||
int val1 = Do10(=> FuncA, 3);
|
||||
Test.Assert(val1 == 300);
|
||||
|
||||
int val2 = FuncRefs2.Do10Ext(=> FuncA, 3);
|
||||
Test.Assert(val2 == 300);
|
||||
|
||||
float val3 = Do10f(scope => FuncA, 0.34f);
|
||||
Test.Assert(val3 == -34);
|
||||
|
||||
float val4 = Do10f(=> FuncA, 0.34f);
|
||||
Test.Assert(val4 == -34);
|
||||
}
|
||||
|
||||
struct MethodRefHolder<T> where T : delegate int(int num)
|
||||
{
|
||||
public T mVal;
|
||||
|
||||
public void Set(T val) mut
|
||||
{
|
||||
mVal = val;
|
||||
}
|
||||
|
||||
public int Use(int num)
|
||||
{
|
||||
return mVal(num);
|
||||
}
|
||||
|
||||
[SkipCall]
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension MethodRefHolder<T> where T : Delegate
|
||||
{
|
||||
public void Dispose()
|
||||
{
|
||||
delete mVal;
|
||||
}
|
||||
}
|
||||
|
||||
static int Use<T>(T val, int num) where T : delegate int(int num)
|
||||
{
|
||||
T copied = val;
|
||||
copied(num);
|
||||
int result = val(num);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static MethodRefHolder<T> Bind<T>(T val) where T : delegate int(int num)
|
||||
{
|
||||
MethodRefHolder<T> bind = .();
|
||||
bind.Set(val);
|
||||
return bind;
|
||||
}
|
||||
|
||||
class Class
|
||||
{
|
||||
public int32 mA = 100;
|
||||
public int16 mB = 200;
|
||||
|
||||
public void Test()
|
||||
{
|
||||
int a = 0;
|
||||
Splattable splat;
|
||||
splat.mA = 300;
|
||||
splat.mB = 400;
|
||||
|
||||
int LFunc(int p)
|
||||
{
|
||||
a += p;
|
||||
mA += splat.mA;
|
||||
return splat.mB;
|
||||
}
|
||||
|
||||
Test.Assert(Use(=> LFunc, 10) == 400);
|
||||
Test.Assert(a == 10+10);
|
||||
Test.Assert(mA == 100+300+300);
|
||||
|
||||
var bind = Bind(=> LFunc);
|
||||
|
||||
Test.Assert(bind.Use(30) == 400);
|
||||
Test.Assert(a == 10+10 + 30);
|
||||
Test.Assert(mA == 100+300+300 + 300);
|
||||
|
||||
bind.Dispose();
|
||||
}
|
||||
|
||||
public void TestDlg()
|
||||
{
|
||||
int a = 0;
|
||||
Splattable splat;
|
||||
splat.mA = 300;
|
||||
splat.mB = 400;
|
||||
|
||||
int LFunc(int p)
|
||||
{
|
||||
a += p;
|
||||
mA += splat.mA;
|
||||
return splat.mB;
|
||||
}
|
||||
|
||||
delegate int(int num) dlg = new => LFunc;
|
||||
|
||||
Test.Assert(Use(dlg, 10) == 400);
|
||||
Test.Assert(a == 10+10);
|
||||
Test.Assert(mA == 100+300+300);
|
||||
|
||||
var bind = Bind(dlg);
|
||||
|
||||
Test.Assert(bind.Use(30) == 400);
|
||||
Test.Assert(a == 10+10 + 30);
|
||||
Test.Assert(mA == 100+300+300 + 300);
|
||||
|
||||
bind.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
struct Valueless
|
||||
{
|
||||
public void Test() mut
|
||||
{
|
||||
int a = 0;
|
||||
Splattable splat;
|
||||
splat.mA = 300;
|
||||
splat.mB = 400;
|
||||
|
||||
int LFunc(int p)
|
||||
{
|
||||
a += p;
|
||||
a += GetVal();
|
||||
return splat.mB;
|
||||
}
|
||||
|
||||
Test.Assert(Use(=> LFunc, 10) == 400);
|
||||
Test.Assert(a == 10*2+20*2);
|
||||
|
||||
var bind = Bind(=> LFunc);
|
||||
|
||||
Test.Assert(bind.Use(30) == 400);
|
||||
Test.Assert(a == 10*2+20*2 + 30+20);
|
||||
|
||||
bind.Dispose();
|
||||
}
|
||||
|
||||
public void TestDlg()
|
||||
{
|
||||
int a = 0;
|
||||
Splattable splat;
|
||||
splat.mA = 300;
|
||||
splat.mB = 400;
|
||||
|
||||
int LFunc(int p)
|
||||
{
|
||||
a += p;
|
||||
a += GetVal();
|
||||
return splat.mB;
|
||||
}
|
||||
|
||||
delegate int(int num) dlg = new => LFunc;
|
||||
|
||||
Test.Assert(Use(dlg, 10) == 400);
|
||||
Test.Assert(a == 10*2+20*2);
|
||||
|
||||
var bind = Bind(dlg);
|
||||
|
||||
Test.Assert(bind.Use(30) == 400);
|
||||
Test.Assert(a == 10*2+20*2 + 30+20);
|
||||
|
||||
bind.Dispose();
|
||||
}
|
||||
|
||||
public int GetVal()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
||||
struct Splattable
|
||||
{
|
||||
public int32 mA = 100;
|
||||
public int16 mB = 200;
|
||||
|
||||
public void Test() mut
|
||||
{
|
||||
int a = 0;
|
||||
Splattable splat;
|
||||
splat.mA = 300;
|
||||
splat.mB = 400;
|
||||
|
||||
int LFunc(int p)
|
||||
{
|
||||
a += p;
|
||||
mA += splat.mA;
|
||||
return splat.mB;
|
||||
}
|
||||
|
||||
Test.Assert(Use(=> LFunc, 10) == 400);
|
||||
Test.Assert(a == 10+10);
|
||||
Test.Assert(mA == 100+300+300);
|
||||
|
||||
var bind = Bind(=> LFunc);
|
||||
|
||||
Test.Assert(bind.Use(30) == 400);
|
||||
Test.Assert(a == 10+10 + 30);
|
||||
Test.Assert(mA == 100+300+300 + 300);
|
||||
|
||||
bind.Dispose();
|
||||
}
|
||||
|
||||
public void TestDlg() mut
|
||||
{
|
||||
int a = 0;
|
||||
Splattable splat;
|
||||
splat.mA = 300;
|
||||
splat.mB = 400;
|
||||
|
||||
int LFunc(int p)
|
||||
{
|
||||
a += p;
|
||||
mA += splat.mA;
|
||||
return splat.mB;
|
||||
}
|
||||
|
||||
delegate int(int num) dlg = new => LFunc;
|
||||
|
||||
Test.Assert(Use(dlg, 10) == 400);
|
||||
Test.Assert(a == 10+10);
|
||||
Test.Assert(mA == 100+300+300);
|
||||
|
||||
var bind = Bind(dlg);
|
||||
|
||||
Test.Assert(bind.Use(30) == 400);
|
||||
Test.Assert(a == 10+10 + 30);
|
||||
Test.Assert(mA == 100+300+300 + 300);
|
||||
|
||||
bind.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
struct NonSplattable
|
||||
{
|
||||
public int32 mA = 100;
|
||||
public int16 mB = 200;
|
||||
public int64 mC = 300;
|
||||
public int64 mD = 400;
|
||||
|
||||
public void Test() mut
|
||||
{
|
||||
int a = 0;
|
||||
Splattable splat;
|
||||
splat.mA = 300;
|
||||
splat.mB = 400;
|
||||
|
||||
int LFunc(int p)
|
||||
{
|
||||
a += p;
|
||||
mA += splat.mA;
|
||||
return splat.mB;
|
||||
}
|
||||
|
||||
Test.Assert(Use(=> LFunc, 10) == 400);
|
||||
Test.Assert(a == 10+10);
|
||||
Test.Assert(mA == 100+300+300);
|
||||
|
||||
var bind = Bind(=> LFunc);
|
||||
|
||||
Test.Assert(bind.Use(30) == 400);
|
||||
Test.Assert(a == 10+10 + 30);
|
||||
Test.Assert(mA == 100+300+300 + 300);
|
||||
|
||||
bind.Dispose();
|
||||
}
|
||||
|
||||
public void TestDlg() mut
|
||||
{
|
||||
int a = 0;
|
||||
Splattable splat;
|
||||
splat.mA = 300;
|
||||
splat.mB = 400;
|
||||
|
||||
int LFunc(int p)
|
||||
{
|
||||
a += p;
|
||||
mA += splat.mA;
|
||||
return splat.mB;
|
||||
}
|
||||
|
||||
delegate int(int num) dlg = new => LFunc;
|
||||
|
||||
Test.Assert(Use(dlg, 10) == 400);
|
||||
Test.Assert(a == 10+10);
|
||||
Test.Assert(mA == 100+300+300);
|
||||
|
||||
var bind = Bind(dlg);
|
||||
|
||||
Test.Assert(bind.Use(30) == 400);
|
||||
Test.Assert(a == 10+10 + 30);
|
||||
Test.Assert(mA == 100+300+300 + 300);
|
||||
|
||||
bind.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void ClassTestA()
|
||||
{
|
||||
Class val = scope Class();
|
||||
val.Test();
|
||||
val = scope Class();
|
||||
val.TestDlg();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void ValuelessTestA()
|
||||
{
|
||||
Valueless val = .();
|
||||
val.Test();
|
||||
val = .();
|
||||
val.TestDlg();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void SplattableTestA()
|
||||
{
|
||||
Splattable val = .();
|
||||
val.Test();
|
||||
val = .();
|
||||
val.TestDlg();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void NonSplattableTestA()
|
||||
{
|
||||
NonSplattable val = .();
|
||||
val.Test();
|
||||
val = .();
|
||||
val.TestDlg();
|
||||
}
|
||||
}
|
||||
}
|
13
IDEHelper/Tests/src/Helper.bf
Normal file
13
IDEHelper/Tests/src/Helper.bf
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace System.Collections.Generic
|
||||
{
|
||||
class TClass<T> : IDisposable
|
||||
{
|
||||
public void Dispose()
|
||||
{
|
||||
Variant GetVariant()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
127
IDEHelper/Tests/src/Interfaces.bf
Normal file
127
IDEHelper/Tests/src/Interfaces.bf
Normal file
|
@ -0,0 +1,127 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Interfaces
|
||||
{
|
||||
interface IFaceA
|
||||
{
|
||||
int FuncA(int a) mut;
|
||||
int FuncA2() mut { return 0; }
|
||||
}
|
||||
|
||||
interface IFaceB : IFaceA
|
||||
{
|
||||
void FuncB(int a) mut
|
||||
{
|
||||
FuncA(a + 100);
|
||||
}
|
||||
}
|
||||
|
||||
concrete interface IFaceC
|
||||
{
|
||||
concrete IFaceA GetConcreteIA();
|
||||
}
|
||||
|
||||
struct StructA : IFaceB
|
||||
{
|
||||
public int mA = 10;
|
||||
|
||||
int IFaceA.FuncA(int a) mut
|
||||
{
|
||||
mA += a;
|
||||
return mA;
|
||||
}
|
||||
}
|
||||
|
||||
struct StructB : IFaceC
|
||||
{
|
||||
public StructA GetConcreteIA()
|
||||
{
|
||||
return StructA();
|
||||
}
|
||||
}
|
||||
|
||||
static int UseIA<T>(mut T val, int a) where T : IFaceA
|
||||
{
|
||||
return val.FuncA(a);
|
||||
}
|
||||
|
||||
static int UseIA2<T>(mut T val) where T : IFaceA
|
||||
{
|
||||
return val.FuncA2();
|
||||
}
|
||||
|
||||
static void UseIB<T>(mut T val, int a) where T : IFaceB
|
||||
{
|
||||
val.FuncB(a);
|
||||
}
|
||||
|
||||
class ClassA : IFaceA
|
||||
{
|
||||
public int FuncA(int a)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public virtual int FuncA2()
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassB : ClassA
|
||||
{
|
||||
public new int FuncA(int a)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
public override int FuncA2()
|
||||
{
|
||||
return 60;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassC : ClassA, IFaceA
|
||||
{
|
||||
public new int FuncA(int a)
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
||||
public override int FuncA2()
|
||||
{
|
||||
return 70;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
StructA sa = .();
|
||||
UseIB(mut sa, 9);
|
||||
Test.Assert(sa.mA == 119);
|
||||
|
||||
ClassA ca = scope ClassA();
|
||||
ClassB cb = scope ClassB();
|
||||
ClassA cba = cb;
|
||||
ClassC cc = scope ClassC();
|
||||
ClassA cca = cc;
|
||||
|
||||
Test.Assert(UseIA(ca, 100) == 5);
|
||||
Test.Assert(UseIA(cb, 100) == 5);
|
||||
Test.Assert(UseIA(cba, 100) == 5);
|
||||
Test.Assert(UseIA((IFaceA)cba, 100) == 5);
|
||||
Test.Assert(UseIA(cc, 100) == 7);
|
||||
Test.Assert(UseIA(cca, 100) == 5);
|
||||
|
||||
Test.Assert(UseIA2(ca) == 50);
|
||||
Test.Assert(UseIA2(cb) == 60);
|
||||
Test.Assert(UseIA2(cba) == 60);
|
||||
Test.Assert(UseIA2((IFaceA)cba) == 60);
|
||||
Test.Assert(UseIA2(cc) == 70);
|
||||
Test.Assert(UseIA2(cca) == 70);
|
||||
}
|
||||
}
|
||||
}
|
25
IDEHelper/Tests/src/Ints.bf
Normal file
25
IDEHelper/Tests/src/Ints.bf
Normal file
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Ints
|
||||
{
|
||||
[Test]
|
||||
public static void TestUInt64()
|
||||
{
|
||||
var str = scope String();
|
||||
|
||||
uint64 val = 0x11223344'55667788;
|
||||
|
||||
str.AppendF("{0:X}", val);
|
||||
//Test.Assert(str == "1122334455667788");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestInt64()
|
||||
{
|
||||
Test.Assert(Math.Min((int64)-1, (int64)0) == -1);
|
||||
Test.Assert(Math.Max((int64)-1, (int64)0) == 0);
|
||||
}
|
||||
}
|
||||
}
|
40
IDEHelper/Tests/src/Lambdas.bf
Normal file
40
IDEHelper/Tests/src/Lambdas.bf
Normal file
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Lambdas
|
||||
{
|
||||
[Test]
|
||||
static void TestBasics()
|
||||
{
|
||||
int a = 1;
|
||||
|
||||
Action act = scope [&] () =>
|
||||
{
|
||||
Action act2 = scope [&] () =>
|
||||
{
|
||||
a += 100;
|
||||
};
|
||||
act2();
|
||||
};
|
||||
act();
|
||||
|
||||
Test.Assert(a == 101);
|
||||
}
|
||||
|
||||
static int Add3<T>(T func) where T : delegate int()
|
||||
{
|
||||
return func() + func() + func();
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestValueless()
|
||||
{
|
||||
Test.Assert(Add3(() => 100) == 300);
|
||||
|
||||
int a = 20;
|
||||
int result = Add3(() => a++);
|
||||
Test.Assert(result == 63);
|
||||
}
|
||||
}
|
||||
}
|
346
IDEHelper/Tests/src/LocalFunctions.bf
Normal file
346
IDEHelper/Tests/src/LocalFunctions.bf
Normal file
|
@ -0,0 +1,346 @@
|
|||
#pragma warning disable 168
|
||||
|
||||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class LocalFunctions
|
||||
{
|
||||
[Test]
|
||||
static void TestA()
|
||||
{
|
||||
int a = 1;
|
||||
|
||||
void FuncA()
|
||||
{
|
||||
void FuncB()
|
||||
{
|
||||
a += 100;
|
||||
}
|
||||
|
||||
FuncB();
|
||||
}
|
||||
|
||||
FuncA();
|
||||
Test.Assert(a == 101);
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestB()
|
||||
{
|
||||
int a = 1;
|
||||
Action act = scope [&] () =>
|
||||
{
|
||||
a += 100;
|
||||
};
|
||||
act();
|
||||
Test.Assert(a == 101);
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestC()
|
||||
{
|
||||
int a = 1;
|
||||
const int c = 10;
|
||||
|
||||
Action OuterLocal()
|
||||
{
|
||||
return new [&] () =>
|
||||
{
|
||||
void FuncA()
|
||||
{
|
||||
FuncB();
|
||||
}
|
||||
|
||||
void FuncB()
|
||||
{
|
||||
a += c;
|
||||
}
|
||||
|
||||
FuncA();
|
||||
};
|
||||
}
|
||||
|
||||
var act = OuterLocal();
|
||||
act();
|
||||
delete act;
|
||||
Test.Assert(a == 11);
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestD()
|
||||
{
|
||||
int a = 1;
|
||||
int b = 2;
|
||||
|
||||
void FuncA()
|
||||
{
|
||||
a += 100;
|
||||
}
|
||||
|
||||
mixin MixA(var refVal)
|
||||
{
|
||||
refVal += 10;
|
||||
FuncA();
|
||||
MixB!();
|
||||
}
|
||||
|
||||
mixin MixB()
|
||||
{
|
||||
b += 20;
|
||||
}
|
||||
|
||||
MixA!(b);
|
||||
Test.Assert(a == 101);
|
||||
Test.Assert(b == 32);
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestE()
|
||||
{
|
||||
int a = 1;
|
||||
int b = 2;
|
||||
int c = 3;
|
||||
|
||||
void FuncA()
|
||||
{
|
||||
a += 100;
|
||||
FuncB();
|
||||
b += 200;
|
||||
}
|
||||
|
||||
void FuncB()
|
||||
{
|
||||
c += 300;
|
||||
}
|
||||
|
||||
FuncA();
|
||||
Test.Assert(a == 101);
|
||||
Test.Assert(b == 202);
|
||||
Test.Assert(c == 303);
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestF()
|
||||
{
|
||||
int a = 1;
|
||||
const int c = 100;
|
||||
|
||||
Action act = scope [&] () =>
|
||||
{
|
||||
void FuncA()
|
||||
{
|
||||
FuncB();
|
||||
|
||||
const int d = 1000;
|
||||
|
||||
void FuncB()
|
||||
{
|
||||
a += c;
|
||||
a += d;
|
||||
}
|
||||
}
|
||||
|
||||
FuncA();
|
||||
};
|
||||
act();
|
||||
Test.Assert(a == 1101);
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestG()
|
||||
{
|
||||
int a = 1;
|
||||
|
||||
void FuncA()
|
||||
{
|
||||
a += 100;
|
||||
|
||||
int a = 2;
|
||||
|
||||
void FuncB()
|
||||
{
|
||||
a += 1000;
|
||||
}
|
||||
|
||||
FuncB();
|
||||
}
|
||||
|
||||
FuncA();
|
||||
Test.Assert(a == 101);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestH()
|
||||
{
|
||||
int a = 1;
|
||||
|
||||
void FuncA(int b)
|
||||
{
|
||||
a += 100;
|
||||
if (b == 0)
|
||||
FuncB();
|
||||
}
|
||||
|
||||
void FuncB()
|
||||
{
|
||||
Action act = scope [&] () =>
|
||||
{
|
||||
FuncA(1);
|
||||
};
|
||||
|
||||
act();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestI()
|
||||
{
|
||||
int a = 1;
|
||||
|
||||
void FuncA()
|
||||
{
|
||||
a += 100;
|
||||
}
|
||||
|
||||
void FuncB()
|
||||
{
|
||||
int a = 2;
|
||||
FuncA();
|
||||
}
|
||||
|
||||
FuncB();
|
||||
Test.Assert(a == 101);
|
||||
}
|
||||
|
||||
class ClassA
|
||||
{
|
||||
public int mA;
|
||||
|
||||
public mixin MixA()
|
||||
{
|
||||
mA += 10;
|
||||
|
||||
void LocalA()
|
||||
{
|
||||
mA += 20;
|
||||
}
|
||||
}
|
||||
|
||||
public void FuncA()
|
||||
{
|
||||
MixA!();
|
||||
}
|
||||
|
||||
public (int, int) MethodT<T>()
|
||||
{
|
||||
int a = 8;
|
||||
int b = 90;
|
||||
|
||||
int FuncT<T2>()
|
||||
{
|
||||
int GetIt()
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
int GetIt<T3>(T3 val)
|
||||
{
|
||||
return sizeof(T3);
|
||||
}
|
||||
|
||||
return mA + sizeof(T)*10000 + sizeof(T2)*1000 + GetIt<float>(2.0f)*100 + GetIt() + a;
|
||||
}
|
||||
|
||||
|
||||
int val = FuncT<int8>();
|
||||
return (FuncT<int8>(), FuncT<int16>());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestJ()
|
||||
{
|
||||
int a = 8;
|
||||
int b = 90;
|
||||
|
||||
int FuncT<T>()
|
||||
{
|
||||
int GetIt()
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
int GetIt<T2>(T2 val)
|
||||
{
|
||||
return sizeof(T2);
|
||||
}
|
||||
|
||||
return sizeof(T)*1000 + GetIt(2.0f)*100 + GetIt() + a;
|
||||
}
|
||||
|
||||
Test.Assert(FuncT<int8>() == 1498);
|
||||
Test.Assert(FuncT<int16>() == 2498);
|
||||
|
||||
///
|
||||
ClassA ca = scope ClassA();
|
||||
ca.mA = 300000;
|
||||
let res2 = ca.MethodT<int32>();
|
||||
Test.Assert(res2.0 == 341498);
|
||||
Test.Assert(res2.1 == 342498);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestK()
|
||||
{
|
||||
int a = 8;
|
||||
int b = 90;
|
||||
|
||||
int GetIt(Object val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetIt(int8 val)
|
||||
{
|
||||
return a + val;
|
||||
}
|
||||
|
||||
int GetIt(int16 val)
|
||||
{
|
||||
return b + val;
|
||||
}
|
||||
|
||||
// We want to ensure that each specialization of Get<T> has its own capture list
|
||||
int Get<T>(T val)
|
||||
{
|
||||
return GetIt(val);
|
||||
}
|
||||
|
||||
Test.Assert(GetIt((int8)100) == 108);
|
||||
Test.Assert(GetIt((int16)100) == 190);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestL()
|
||||
{
|
||||
int a = 8;
|
||||
|
||||
int LocalA()
|
||||
{
|
||||
return 9;
|
||||
}
|
||||
|
||||
int LocalB()
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
function int() func = => LocalA;
|
||||
Test.Assert(func() == 9);
|
||||
|
||||
delegate int() dlg = scope => LocalB;
|
||||
Test.Assert(dlg() == 8);
|
||||
}
|
||||
}
|
||||
}
|
47
IDEHelper/Tests/src/Mixins.bf
Normal file
47
IDEHelper/Tests/src/Mixins.bf
Normal file
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Mixins
|
||||
{
|
||||
class MixClass
|
||||
{
|
||||
public int mA = 100;
|
||||
|
||||
public mixin MixA(var addTo)
|
||||
{
|
||||
mA += addTo;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
MixClass mc = scope MixClass();
|
||||
mc.MixA!(10);
|
||||
Test.Assert(mc.mA == 110);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestLocalMixin()
|
||||
{
|
||||
mixin AppendAndNullify(String str)
|
||||
{
|
||||
int a = 1;
|
||||
a++;
|
||||
str.Append("B");
|
||||
str = null;
|
||||
}
|
||||
|
||||
int a = 2;
|
||||
a++;
|
||||
|
||||
String str0 = scope String("A");
|
||||
String str1 = str0;
|
||||
|
||||
AppendAndNullify!(str0);
|
||||
Test.Assert(str0 == null);
|
||||
Test.Assert(str1 == "AB");
|
||||
}
|
||||
}
|
||||
}
|
89
IDEHelper/Tests/src/NullConditional.bf
Normal file
89
IDEHelper/Tests/src/NullConditional.bf
Normal file
|
@ -0,0 +1,89 @@
|
|||
#pragma warning disable 168
|
||||
|
||||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class CondB
|
||||
{
|
||||
public int mInt = 123;
|
||||
|
||||
public int Val
|
||||
{
|
||||
get
|
||||
{
|
||||
return 234;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetVal()
|
||||
{
|
||||
return 345;
|
||||
}
|
||||
}
|
||||
|
||||
class CondA
|
||||
{
|
||||
public CondB mCondB;
|
||||
public CondB mCondB2;
|
||||
|
||||
CondB CondBVal
|
||||
{
|
||||
get
|
||||
{
|
||||
return mCondB;
|
||||
}
|
||||
}
|
||||
|
||||
CondB GetCondB()
|
||||
{
|
||||
return mCondB;
|
||||
}
|
||||
}
|
||||
|
||||
class NullConditional
|
||||
{
|
||||
[Test]
|
||||
static void TestBasic()
|
||||
{
|
||||
CondA ca = scope CondA();
|
||||
ca.mCondB = scope CondB();
|
||||
if (int i = ca?.mCondB?.mInt)
|
||||
Test.Assert(i == 123);
|
||||
else
|
||||
Test.FatalError();
|
||||
|
||||
if (let i = ca?.mCondB?.mInt)
|
||||
{
|
||||
Test.Assert(typeof(decltype(i)) == typeof(int));
|
||||
Test.Assert(i == 123);
|
||||
}
|
||||
else
|
||||
Test.FatalError();
|
||||
|
||||
var i2 = ca?.mCondB?.Val;
|
||||
Test.Assert(i2.Value == 234);
|
||||
|
||||
var i3 = ca?.mCondB?.GetVal();
|
||||
Test.Assert(i3.Value == 345);
|
||||
|
||||
if (int i4 = ca?.mCondB2?.mInt)
|
||||
{
|
||||
Test.FatalError();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestParen()
|
||||
{
|
||||
CondA ca = scope CondA();
|
||||
ca.mCondB = scope CondB();
|
||||
|
||||
let i = (ca?.mCondB?.mInt).GetValueOrDefault();
|
||||
Test.Assert(i == 123);
|
||||
|
||||
let i2 = (ca?.mCondB2?.mInt).GetValueOrDefault();
|
||||
Test.Assert(i2 == 0);
|
||||
}
|
||||
}
|
||||
}
|
21
IDEHelper/Tests/src/Objects.bf
Normal file
21
IDEHelper/Tests/src/Objects.bf
Normal file
|
@ -0,0 +1,21 @@
|
|||
namespace Tests
|
||||
{
|
||||
class Objects
|
||||
{
|
||||
class ClassA
|
||||
{
|
||||
public virtual void MethodA()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class ClassB : ClassA
|
||||
{
|
||||
public override void MethodA()
|
||||
{
|
||||
base.MethodA();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
38
IDEHelper/Tests/src/Operators.bf
Normal file
38
IDEHelper/Tests/src/Operators.bf
Normal file
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Operators
|
||||
{
|
||||
struct StructA
|
||||
{
|
||||
public int mA;
|
||||
|
||||
public static StructA operator+(StructA lhs, StructA rhs)
|
||||
{
|
||||
StructA res;
|
||||
res.mA = lhs.mA + rhs.mA;
|
||||
return res;
|
||||
}
|
||||
|
||||
public static StructA operator-(StructA lhs, StructA rhs)
|
||||
{
|
||||
StructA res;
|
||||
res.mA = lhs.mA - rhs.mA;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
StructA sa0 = default;
|
||||
sa0.mA = 1;
|
||||
StructA sa1 = default;
|
||||
sa1.mA = 2;
|
||||
|
||||
StructA sa2 = sa0 + sa1;
|
||||
Test.Assert(sa2.mA == 3);
|
||||
}
|
||||
}
|
||||
}
|
19
IDEHelper/Tests/src/Precedence.bf
Normal file
19
IDEHelper/Tests/src/Precedence.bf
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Precedence
|
||||
{
|
||||
[Test]
|
||||
static void Test()
|
||||
{
|
||||
int a = -1;
|
||||
bool b = true;
|
||||
bool c = true;
|
||||
if (a == -1 && b && c)
|
||||
a = 2;
|
||||
Test.Assert(a == 2);
|
||||
Test.Assert(1*10 + 2 + 3 + 5*100*10 + 6*10000 == 65015);
|
||||
}
|
||||
}
|
||||
}
|
163
IDEHelper/Tests/src/Reflection.bf
Normal file
163
IDEHelper/Tests/src/Reflection.bf
Normal file
|
@ -0,0 +1,163 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Reflection
|
||||
{
|
||||
[AttributeUsage(.Field, .ReflectAttribute)]
|
||||
struct AttrAAttribute : Attribute
|
||||
{
|
||||
public int32 mA;
|
||||
public float mB;
|
||||
public String mC;
|
||||
public String mD;
|
||||
|
||||
public this(int32 a, float b, String c, String d)
|
||||
{
|
||||
PrintF("this: %p A: %d B: %f", this, a, (double)b);
|
||||
|
||||
mA = a;
|
||||
mB = b;
|
||||
mC = c;
|
||||
mD = d;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(.Field)]
|
||||
struct AttrBAttribute : Attribute
|
||||
{
|
||||
int32 mA;
|
||||
float mB;
|
||||
|
||||
public this(int32 a, float b)
|
||||
{
|
||||
mA = a;
|
||||
mB = b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Reflect]
|
||||
class ClassA
|
||||
{
|
||||
[AlwaysInclude]
|
||||
static float StaticMethodA(int32 a, int32 b, float c)
|
||||
{
|
||||
return a + b + c;
|
||||
}
|
||||
|
||||
[AlwaysInclude]
|
||||
float MemberMethodA(int32 a, int32 b, float c)
|
||||
{
|
||||
return a + b + c;
|
||||
}
|
||||
|
||||
public virtual int GetA(int32 a)
|
||||
{
|
||||
return a + 1000;
|
||||
}
|
||||
|
||||
public virtual int GetB(int32 a)
|
||||
{
|
||||
return a + 3000;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassA2 : ClassA
|
||||
{
|
||||
public override int GetA(int32 a)
|
||||
{
|
||||
return a + 2000;
|
||||
}
|
||||
|
||||
public override int GetB(int32 a)
|
||||
{
|
||||
return a + 4000;
|
||||
}
|
||||
}
|
||||
|
||||
[Reflect(.All)]
|
||||
class ClassB
|
||||
{
|
||||
[AttrA(11, 22, "StrA", "StrB")]
|
||||
int mA;
|
||||
[AttrB(44, 55)]
|
||||
int mB;
|
||||
int mC;
|
||||
}
|
||||
|
||||
[Reflect(.Type)]
|
||||
class ClassC
|
||||
{
|
||||
[AttrA(11, 22, "StrA", "StrC")]
|
||||
int mA;
|
||||
[AttrB(44, 55)]
|
||||
int mB;
|
||||
int mC;
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestA()
|
||||
{
|
||||
ClassA ca = scope ClassA();
|
||||
ClassA2 ca2 = scope ClassA2();
|
||||
Test.Assert(ca2.GetA(9) == 2009);
|
||||
|
||||
int methodIdx = 0;
|
||||
var typeInfo = typeof(ClassA);
|
||||
for (let methodInfo in typeInfo.GetMethods())
|
||||
{
|
||||
switch (methodIdx)
|
||||
{
|
||||
case 0:
|
||||
Test.Assert(methodInfo.Name == "StaticMethodA");
|
||||
var result = methodInfo.Invoke(null, 100, (int32)20, 3.0f).Get();
|
||||
Test.Assert(result.Get<float>() == 123);
|
||||
result.Dispose();
|
||||
case 1:
|
||||
Test.Assert(methodInfo.Name == "MemberMethodA");
|
||||
var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get();
|
||||
Test.Assert(result.Get<float>() == 123);
|
||||
result.Dispose();
|
||||
case 2:
|
||||
Test.Assert(methodInfo.Name == "GetA");
|
||||
var result = methodInfo.Invoke(ca, 123).Get();
|
||||
Test.Assert(result.Get<int>() == 1123);
|
||||
result.Dispose();
|
||||
result = methodInfo.Invoke(ca2, 123).Get();
|
||||
Test.Assert(result.Get<int>() == 2123);
|
||||
result.Dispose();
|
||||
case 3:
|
||||
Test.Assert(methodInfo.Name == "__BfCtor");
|
||||
Test.Assert(methodInfo.IsConstructor);
|
||||
case 4:
|
||||
Test.FatalError(); // Shouldn't have any more
|
||||
}
|
||||
|
||||
methodIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestB()
|
||||
{
|
||||
ClassB cb = scope ClassB();
|
||||
int fieldIdx = 0;
|
||||
for (let fieldInfo in cb.GetType().GetFields())
|
||||
{
|
||||
switch (fieldIdx)
|
||||
{
|
||||
case 0:
|
||||
Test.Assert(fieldInfo.Name == "mA");
|
||||
var attrA = fieldInfo.GetCustomAttribute<AttrAAttribute>().Get();
|
||||
Test.Assert(attrA.mA == 11);
|
||||
Test.Assert(attrA.mB == 22);
|
||||
Test.Assert(attrA.mC == "StrA");
|
||||
Test.Assert(attrA.mD == "StrB");
|
||||
}
|
||||
|
||||
fieldIdx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
177
IDEHelper/Tests/src/Scopes.bf
Normal file
177
IDEHelper/Tests/src/Scopes.bf
Normal file
|
@ -0,0 +1,177 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Scopes
|
||||
{
|
||||
[Test]
|
||||
public static void TestRestore()
|
||||
{
|
||||
// This shouldn't overflow because we should restore the stack between 'i' iterations
|
||||
for (int i < 100)
|
||||
IBlock:
|
||||
{
|
||||
// Allocate 500kb
|
||||
for (int j < 5)
|
||||
{
|
||||
scope:IBlock uint8[100*1024];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestGetStrScope()
|
||||
{
|
||||
var str = GetStr!();
|
||||
Test.Assert(str == "TestString");
|
||||
|
||||
{
|
||||
str = GetStr!::();
|
||||
}
|
||||
Test.Assert(str == "TestString");
|
||||
}
|
||||
|
||||
/*[Test(ShouldFail=true)]
|
||||
public static void TestFailGetStrScope()
|
||||
{
|
||||
String str;
|
||||
{
|
||||
str = GetStr!();
|
||||
}
|
||||
// Should detect as deleted
|
||||
#unwarn
|
||||
str.Contains('T');
|
||||
}*/
|
||||
|
||||
public static mixin GetStr()
|
||||
{
|
||||
scope:mixin String("TestString")
|
||||
}
|
||||
|
||||
class ClassA
|
||||
{
|
||||
public int mA = 123;
|
||||
public static int sAllocCount = 0;
|
||||
|
||||
public this()
|
||||
{
|
||||
sAllocCount++;
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
Test.Assert(mA == 123);
|
||||
sAllocCount--;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassB
|
||||
{
|
||||
public int mA = 234;
|
||||
public static int sAllocCount = 0;
|
||||
|
||||
public this()
|
||||
{
|
||||
sAllocCount++;
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
Test.Assert(mA == 234);
|
||||
sAllocCount--;
|
||||
}
|
||||
}
|
||||
|
||||
static bool CheckTrue(Object obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CheckFalse(Object obj)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestIf()
|
||||
{
|
||||
//
|
||||
{
|
||||
if ((CheckTrue(scope ClassA())) || (CheckTrue(scope ClassB())))
|
||||
{
|
||||
Test.Assert(ClassA.sAllocCount == 1);
|
||||
Test.Assert(ClassB.sAllocCount == 0);
|
||||
}
|
||||
Test.Assert(ClassA.sAllocCount == 0);
|
||||
Test.Assert(ClassB.sAllocCount == 0);
|
||||
}
|
||||
|
||||
//
|
||||
{
|
||||
if ((CheckFalse(scope ClassA())) || (CheckTrue(scope ClassB())))
|
||||
{
|
||||
Test.Assert(ClassA.sAllocCount == 1);
|
||||
Test.Assert(ClassB.sAllocCount == 1);
|
||||
}
|
||||
Test.Assert(ClassA.sAllocCount == 0);
|
||||
Test.Assert(ClassB.sAllocCount == 0);
|
||||
}
|
||||
|
||||
//
|
||||
{
|
||||
if ((CheckFalse(scope ClassA())) || (CheckFalse(scope ClassB())))
|
||||
{
|
||||
Test.FatalError();
|
||||
}
|
||||
else
|
||||
{
|
||||
Test.Assert(ClassA.sAllocCount == 1);
|
||||
Test.Assert(ClassB.sAllocCount == 1);
|
||||
}
|
||||
Test.Assert(ClassA.sAllocCount == 0);
|
||||
Test.Assert(ClassB.sAllocCount == 0);
|
||||
}
|
||||
|
||||
//
|
||||
{
|
||||
if ((CheckTrue(scope ClassA())) && (CheckTrue(scope ClassB())))
|
||||
{
|
||||
Test.Assert(ClassA.sAllocCount == 1);
|
||||
Test.Assert(ClassB.sAllocCount == 1);
|
||||
}
|
||||
Test.Assert(ClassA.sAllocCount == 0);
|
||||
Test.Assert(ClassB.sAllocCount == 0);
|
||||
}
|
||||
|
||||
//
|
||||
{
|
||||
if ((CheckTrue(scope ClassA())) && (CheckFalse(scope ClassB())))
|
||||
{
|
||||
Test.FatalError();
|
||||
}
|
||||
else
|
||||
{
|
||||
Test.Assert(ClassA.sAllocCount == 1);
|
||||
Test.Assert(ClassB.sAllocCount == 1);
|
||||
}
|
||||
Test.Assert(ClassA.sAllocCount == 0);
|
||||
Test.Assert(ClassB.sAllocCount == 0);
|
||||
}
|
||||
|
||||
//
|
||||
{
|
||||
if ((CheckFalse(scope ClassA())) && (CheckFalse(scope ClassB())))
|
||||
{
|
||||
Test.FatalError();
|
||||
}
|
||||
else
|
||||
{
|
||||
Test.Assert(ClassA.sAllocCount == 1);
|
||||
Test.Assert(ClassB.sAllocCount == 0);
|
||||
}
|
||||
Test.Assert(ClassA.sAllocCount == 0);
|
||||
Test.Assert(ClassB.sAllocCount == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
IDEHelper/Tests/src/SizedArrays.bf
Normal file
27
IDEHelper/Tests/src/SizedArrays.bf
Normal file
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class SizedArrays
|
||||
{
|
||||
[Test]
|
||||
static void TestBasics()
|
||||
{
|
||||
int[3][2] val0 = .((1, 2), (3, 4), (5, 6));
|
||||
Test.Assert(sizeof(decltype(val0)) == sizeof(int)*6);
|
||||
|
||||
Test.Assert(val0[0][0] == 1);
|
||||
Test.Assert(val0[0][1] == 2);
|
||||
Test.Assert(val0[1][0] == 3);
|
||||
|
||||
int[2] val1 = .(7, 8);
|
||||
val0[1] = val1;
|
||||
|
||||
int[3][2] val2 = .((1, 2), (7, 8), (5, 6));
|
||||
Test.Assert(val0 == val2);
|
||||
val2[0][0] = 9;
|
||||
Test.Assert(val0 != val2);
|
||||
Test.Assert(val2[1] == val1);
|
||||
}
|
||||
}
|
||||
}
|
118
IDEHelper/Tests/src/Structs.bf
Normal file
118
IDEHelper/Tests/src/Structs.bf
Normal file
|
@ -0,0 +1,118 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Structs
|
||||
{
|
||||
struct StructA
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct StructB
|
||||
{
|
||||
public int mA;
|
||||
public int mB;
|
||||
|
||||
public this()
|
||||
{
|
||||
mA = 0;
|
||||
mB = 0;
|
||||
}
|
||||
|
||||
public this(int a, int b)
|
||||
{
|
||||
mA = a;
|
||||
mB = b;
|
||||
}
|
||||
}
|
||||
|
||||
struct StructC
|
||||
{
|
||||
int8 mA;
|
||||
int32 mB;
|
||||
int8 mC;
|
||||
}
|
||||
|
||||
[Ordered]
|
||||
struct StructD
|
||||
{
|
||||
int8 mA;
|
||||
int32 mB;
|
||||
int8 mC;
|
||||
}
|
||||
|
||||
[CRepr]
|
||||
struct StructE
|
||||
{
|
||||
int8 mA;
|
||||
int32 mB;
|
||||
int8 mC;
|
||||
}
|
||||
|
||||
struct StructF : StructC
|
||||
{
|
||||
int8 mD;
|
||||
}
|
||||
|
||||
struct StructG : StructD
|
||||
{
|
||||
int8 mD;
|
||||
}
|
||||
|
||||
struct StructH : StructE
|
||||
{
|
||||
int8 mD;
|
||||
}
|
||||
|
||||
[CRepr]
|
||||
struct StructI : StructE
|
||||
{
|
||||
int8 mD;
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestBasics()
|
||||
{
|
||||
Test.Assert(sizeof(StructA) == 0);
|
||||
|
||||
StructB sb0 = .(1, 2);
|
||||
StructB sb1;
|
||||
sb1.mA = 1;
|
||||
sb1.mB = 2;
|
||||
Test.Assert(sb0 == sb1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestLayouts()
|
||||
{
|
||||
Test.Assert(sizeof(StructC) == 6);
|
||||
Test.Assert(alignof(StructC) == 4);
|
||||
Test.Assert(strideof(StructC) == 8);
|
||||
|
||||
Test.Assert(sizeof(StructD) == 9);
|
||||
Test.Assert(alignof(StructD) == 4);
|
||||
Test.Assert(strideof(StructD) == 12);
|
||||
|
||||
Test.Assert(sizeof(StructE) == 12);
|
||||
Test.Assert(alignof(StructE) == 4);
|
||||
Test.Assert(strideof(StructE) == 12);
|
||||
|
||||
Test.Assert(sizeof(StructF) == 7);
|
||||
Test.Assert(alignof(StructF) == 4);
|
||||
Test.Assert(strideof(StructF) == 8);
|
||||
|
||||
Test.Assert(sizeof(StructG) == 10);
|
||||
Test.Assert(alignof(StructG) == 4);
|
||||
Test.Assert(strideof(StructG) == 12);
|
||||
|
||||
Test.Assert(sizeof(StructH) == 13);
|
||||
Test.Assert(alignof(StructH) == 4);
|
||||
Test.Assert(strideof(StructH) == 16);
|
||||
|
||||
Test.Assert(sizeof(StructI) == 16);
|
||||
Test.Assert(alignof(StructI) == 4);
|
||||
Test.Assert(strideof(StructI) == 16);
|
||||
}
|
||||
}
|
||||
}
|
22
IDEHelper/Tests/src/TrackedAlloc.bf
Normal file
22
IDEHelper/Tests/src/TrackedAlloc.bf
Normal file
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class TrackedAlloc
|
||||
{
|
||||
public int mLastAllocSize;
|
||||
|
||||
public void* Alloc(int size, int align)
|
||||
{
|
||||
mLastAllocSize = size;
|
||||
let ptr = new uint8[size]*;
|
||||
Internal.MemSet(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
public void Free(void* ptr)
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
}
|
||||
}
|
56
IDEHelper/Tests/src/Tuples.bf
Normal file
56
IDEHelper/Tests/src/Tuples.bf
Normal file
|
@ -0,0 +1,56 @@
|
|||
#pragma warning disable 168
|
||||
|
||||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Tuples
|
||||
{
|
||||
[Test]
|
||||
public static void TestBasic()
|
||||
{
|
||||
let (a, b, c) = (1, 2, 3);
|
||||
Test.Assert(a == 1);
|
||||
Test.Assert(b == 2);
|
||||
Test.Assert(c == 3);
|
||||
Test.Assert(typeof(decltype(a)) == typeof(int));
|
||||
|
||||
(int32, float) tVal1 = (1, 2.0f);
|
||||
// Allow conversion from named to unnamed
|
||||
tVal1 = (int32 a, float b)(2, 3.0f);
|
||||
|
||||
let v0 = tVal1.0;
|
||||
Test.Assert(v0 == 2);
|
||||
}
|
||||
|
||||
class ValClass
|
||||
{
|
||||
public int mA;
|
||||
|
||||
public int Prop
|
||||
{
|
||||
set
|
||||
{
|
||||
mA = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestDecompose()
|
||||
{
|
||||
ValClass vc = scope .();
|
||||
|
||||
uint8 zz = 202;
|
||||
(var val0, vc.Prop) = (101, zz);
|
||||
Test.Assert(val0 == 101);
|
||||
Test.Assert(vc.mA == 202);
|
||||
|
||||
let tup0 = (111, 222);
|
||||
(int a, int b) tup1 = tup0;
|
||||
Test.Assert(tup0.0 == 111);
|
||||
Test.Assert(tup0.1 == 222);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
123
IDEHelper/Tests/src/TypeLookup.bf
Normal file
123
IDEHelper/Tests/src/TypeLookup.bf
Normal file
|
@ -0,0 +1,123 @@
|
|||
#pragma warning disable 168
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class ClassE
|
||||
{
|
||||
public int mGlobal_E;
|
||||
}
|
||||
|
||||
class TypeLookup
|
||||
{
|
||||
class ClassA
|
||||
{
|
||||
public int mA;
|
||||
}
|
||||
|
||||
class ClassB
|
||||
{
|
||||
private class ClassA
|
||||
{
|
||||
public int mClassB_A2;
|
||||
|
||||
public void Hey()
|
||||
{
|
||||
ClassC cc = scope .();
|
||||
cc.mClassB_C = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public class ClassC
|
||||
{
|
||||
public int mClassB_C;
|
||||
|
||||
public void Hey()
|
||||
{
|
||||
ClassA ca = scope .();
|
||||
ca.mClassB_A2 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ClassC
|
||||
{
|
||||
public int mC;
|
||||
}
|
||||
|
||||
private class ClassE
|
||||
{
|
||||
public int mE;
|
||||
}
|
||||
|
||||
class ClassD : ClassB
|
||||
{
|
||||
public void Hey()
|
||||
{
|
||||
// Shouldn't be able to find ClassB.ClassB since it's private
|
||||
ClassA ca = scope .();
|
||||
ca.mA = 1;
|
||||
|
||||
// We should find ClassB.ClassC since it's public
|
||||
ClassC cc = scope .();
|
||||
cc.mClassB_C = 1;
|
||||
|
||||
ClassE ce = scope .();
|
||||
ce.mE = 2;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassF
|
||||
{
|
||||
private class ClassA
|
||||
{
|
||||
public int mClassF_A;
|
||||
}
|
||||
}
|
||||
|
||||
extension ClassF
|
||||
{
|
||||
public void Hey()
|
||||
{
|
||||
ClassA ca = scope .();
|
||||
ca.mClassF_A = 1;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassG
|
||||
{
|
||||
public class InnerG
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class InnerG2<T>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class ClassH
|
||||
{
|
||||
public class InnerH
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class ClassI : ClassG
|
||||
{
|
||||
class InnerI : ClassH
|
||||
{
|
||||
class InnerInI : InnerG
|
||||
{
|
||||
|
||||
public void UseIt()
|
||||
{
|
||||
InnerG2<int> ig2 = default;
|
||||
InnerH ih = default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
35
IDEHelper/Tests/src/Unions.bf
Normal file
35
IDEHelper/Tests/src/Unions.bf
Normal file
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Unions
|
||||
{
|
||||
// Not really a union
|
||||
[Union]
|
||||
struct UnionA
|
||||
{
|
||||
public int32 mInt32;
|
||||
}
|
||||
|
||||
[Union]
|
||||
struct UnionB
|
||||
{
|
||||
public int32 mInt32;
|
||||
public float mFloat;
|
||||
}
|
||||
|
||||
[Test]
|
||||
static void TestBasics()
|
||||
{
|
||||
UnionA ua = .();
|
||||
ua.mInt32 = 123;
|
||||
Test.Assert(sizeof(UnionA) == 4);
|
||||
|
||||
UnionB ub = .();
|
||||
ub.mInt32 = 123;
|
||||
*((float*)&ub.mInt32) = 1.2f;
|
||||
Test.Assert(ub.mFloat == 1.2f);
|
||||
Test.Assert(sizeof(UnionB) == 4);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue