using System;
using System.Reflection;
using NUnit.Framework;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Burst;
#if BURST_TESTS_ONLY
using Burst.Compiler.IL.DebugInfo;
using Burst.Compiler.IL.Jit;
namespace Unity.Collections.LowLevel.Unsafe
{
internal class DisposeSentinel
{
}
}
#endif
namespace Burst.Compiler.IL.Tests
{
///
/// Tests related to usage of partial managed objects (e.g loading null or storing null
/// reference to a struct, typically used by NativeArray DisposeSentinel)
///
internal class PartialManaged
{
#if BURST_TESTS_ONLY || ENABLE_UNITY_COLLECTIONS_CHECKS
[TestCompiler]
public static int TestWriteNullReference()
{
var element = new Element();
WriteNullReference(out element.Reference);
return element.Value;
}
[BurstDiscard]
private static void WriteNullReference(out DisposeSentinel reference)
{
reference = null;
}
private struct Element
{
#pragma warning disable 0649
public int Value;
public DisposeSentinel Reference;
#pragma warning restore 0649
}
#endif
[TestCompiler]
public static void AssignNullToLocalVariableClass()
{
MyClass x = null;
#pragma warning disable 0219
MyClass value = x;
#pragma warning restore 0219
}
#if BURST_TESTS_ONLY
[Test]
public void TestThrowExceptionOnNonExistingMethod()
{
MethodInfo info = typeof(PartialManaged).GetMethod("NonExistingMethod");
JitCompiler compiler = new JitCompiler(new PortablePdbCache());
Assert.Throws(() => compiler.CompileMethod(info));
}
#endif
[TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_InstructionLdstrNotSupported)]
public static int GetIndexOfCharFomString()
{
return "abc".IndexOf('b');
}
struct StructWithManaged
{
#pragma warning disable 0649
public MyClass myClassValue;
public string stringValue;
public object objectValue;
public float[] arrayValue;
public int value;
#pragma warning restore 0649
}
[TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_TypeNotSupported)]
public static int AccessClassFromStruct()
{
var val = new StructWithManaged();
val.myClassValue.value = val.value;
return val.myClassValue.value;
}
[TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_TypeNotSupported)]
public static void AccessStringFromStruct()
{
var val = new StructWithManaged();
#pragma warning disable 0219
var p = val.stringValue = "abc";
#pragma warning restore 0219
}
[TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_TypeNotSupported)]
public static void AccessObjectFromStruct()
{
var val = new StructWithManaged();
#pragma warning disable 0219
var p = val.objectValue;
p = new object();
#pragma warning restore 0219
}
[TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_TypeNotSupported)]
public static void AccessArrayFromStruct()
{
var val = new StructWithManaged();
var p = val.arrayValue;
p[0] = val.value;
}
[TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_TypeNotSupported)]
public static int GetValueFromStructWithClassField()
{
var val = new StructWithManaged();
val.value = 5;
return val.value;
}
[TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_InstructionNewobjWithManagedTypeNotSupported)]
public static void NewMyClass()
{
#pragma warning disable 0219
var value = new MyClass();
#pragma warning restore 0219
}
private class MyClass
{
public int value;
}
}
}