1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-16 15:24:10 +02:00
Beef/BeefLibs/corlib/src/Reflection/AttributeInfo.bf

641 lines
14 KiB
Beef

using System.Collections;
namespace System.Reflection
{
class AttributeInfo
{
static mixin Decode<T2>(void* data)
{
*((*(T2**)&data)++)
}
public static bool HasCustomAttribute(void* inAttrData, Type attributeType)
{
TypeId findTypeId = attributeType.[Friend]mTypeId;
void* data = inAttrData;
data++;
uint8 count = Decode!<uint8>(data);
for (int32 attrIdx = 0; attrIdx < count; attrIdx++)
AttrBlock:
{
void* startPtr = data;
var len = Decode!<uint16>(data);
void* endPtr = (uint8*)startPtr + len;
var typeId = Decode!<TypeId>(data);
if (typeId == findTypeId)
return true;
data = endPtr;
}
return false;
}
public static Result<void> GetCustomAttribute(void* inAttrData, Type attributeType, Object targetAttr)
{
TypeId findTypeId = attributeType.[Friend]mTypeId;
void* data = inAttrData;
data++;
uint8 count = Decode!<uint8>(data);
for (int32 attrIdx = 0; attrIdx < count; attrIdx++)
AttrBlock:
{
void* startPtr = data;
var len = Decode!<uint16>(data);
void* endPtr = (uint8*)startPtr + len;
var typeId = Decode!<TypeId>(data);
if (typeId != findTypeId)
{
data = endPtr;
continue;
}
var methodIdx = Decode!<uint16>(data);
Type attrType = Type.[Friend]GetType(typeId);
TypeInstance attrTypeInst = attrType as TypeInstance;
MethodInfo methodInfo = .(attrTypeInst, attrTypeInst.[Friend]mMethodDataPtr + methodIdx);
Object[] args = scope Object[methodInfo.[Friend]mData.mMethodData.mParamCount];
int argIdx = 0;
while (data < endPtr)
{
var attrDataType = Decode!<TypeCode>(data);
switch (attrDataType)
{
case .Int8,
.UInt8,
.Char8,
.Boolean:
let attrData = Decode!<int8>(data);
args[argIdx] = scope:AttrBlock box attrData;
case .Int16,
.UInt16,
.Char16:
let attrData = Decode!<int16>(data);
args[argIdx] = scope:AttrBlock box attrData;
case .Int32,
.UInt32,
.Char32:
let attrData = Decode!<int32>(data);
args[argIdx] = scope:AttrBlock box attrData;
case .Float:
let attrData = Decode!<float>(data);
args[argIdx] = scope:AttrBlock box attrData;
case .Int64,
.UInt64,
.Double:
let attrData = Decode!<int64>(data);
args[argIdx] = scope:AttrBlock box attrData;
case (TypeCode)typeof(TypeCode).MaxValue + 8: //BfConstType_TypeOf
let argTypeId = Decode!<int32>(data);
args[argIdx] = Type.[Friend]GetType((.)argTypeId);
case (TypeCode)255:
let stringId = Decode!<int32>(data);
String str = String.[Friend]sIdStringLiterals[stringId];
args[argIdx] = str;
default:
Runtime.FatalError("Not handled");
}
argIdx++;
}
if (methodInfo.Invoke(targetAttr, params args) case .Ok(var val))
val.Dispose();
else
return .Err;
return .Ok;
}
return .Err;
}
public struct CustomAttributeEnumerator : IEnumerator<Variant>, IDisposable
{
void* mData;
int32 mAttrIdx;
uint8 mCount;
Variant mTargetAttr;
public this(void* inAttrData)
{
mData = inAttrData;
mData++;
mAttrIdx = 0;
mCount = mData != null ? AttributeInfo.Decode!<uint8>(mData) : 0;
mTargetAttr = default;
}
public Variant Current
{
get
{
return mTargetAttr;
}
}
public bool MoveNext() mut
{
if (mAttrIdx >= mCount || mData == null)
return false;
void* startPtr = mData;
var len = AttributeInfo.Decode!<uint16>(mData);
void* endPtr = (uint8*)startPtr + len;
var typeId = AttributeInfo.Decode!<TypeId>(mData);
var methodIdx = AttributeInfo.Decode!<uint16>(mData);
Type attrType = Type.[Friend]GetType(typeId);
TypeInstance attrTypeInst = attrType as TypeInstance;
MethodInfo methodInfo = .(attrTypeInst, attrTypeInst.[Friend]mMethodDataPtr + methodIdx);
Object[] args = scope Object[methodInfo.[Friend]mData.mMethodData.mParamCount];
int argIdx = 0;
while (mData < endPtr)
{
var attrDataType = AttributeInfo.Decode!<TypeCode>(mData);
switch (attrDataType)
{
case .Int8,
.UInt8,
.Char8,
.Boolean:
let attrData = AttributeInfo.Decode!<int8>(mData);
args[argIdx] = scope:: box attrData;
case .Int16,
.UInt16,
.Char16:
let attrData = AttributeInfo.Decode!<int16>(mData);
args[argIdx] = scope:: box attrData;
case .Int32,
.UInt32,
.Char32:
let attrData = AttributeInfo.Decode!<int32>(mData);
args[argIdx] = scope:: box attrData;
case .Float:
let attrData = AttributeInfo.Decode!<float>(mData);
args[argIdx] = scope:: box attrData;
case .Int64,
.UInt64,
.Double:
let attrData = AttributeInfo.Decode!<int64>(mData);
args[argIdx] = scope:: box attrData;
case (TypeCode)typeof(TypeCode).MaxValue + 8: //BfConstType_TypeOf
let argTypeId = AttributeInfo.Decode!<int32>(mData);
args[argIdx] = Type.[Friend]GetType((.)argTypeId);
case (TypeCode)255:
let stringId = AttributeInfo.Decode!<int32>(mData);
String str = String.[Friend]sIdStringLiterals[stringId];
args[argIdx] = str;
default:
Runtime.FatalError("Not handled");
}
argIdx++;
}
mTargetAttr.Dispose();
void* data = Variant.Alloc(attrType, out mTargetAttr);
if (methodInfo.Invoke(data, params args) case .Ok(var val))
val.Dispose();
mAttrIdx++;
return true;
}
public void Dispose() mut
{
mTargetAttr.Dispose();
}
public Result<Variant> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
public struct ComptimeTypeCustomAttributeEnumerator : IEnumerator<Variant>, IDisposable
{
int32 mTypeId;
int32 mAttrIdx;
Variant mTargetAttr;
public this(int32 typeId)
{
mTypeId = typeId;
mAttrIdx = -1;
mTargetAttr = default;
}
public Variant Current
{
get
{
return mTargetAttr;
}
}
public bool MoveNext() mut
{
let attrType = Type.[Friend]Comptime_Type_GetCustomAttributeType(mTypeId, ++mAttrIdx);
if (attrType != null)
{
mTargetAttr.Dispose();
void* data = Variant.Alloc(attrType, out mTargetAttr);
if (Type.[Friend]Comptime_Type_GetCustomAttribute(mTypeId, mAttrIdx, data))
return true;
}
return false;
}
public void Dispose() mut
{
mTargetAttr.Dispose();
}
public Result<Variant> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
public struct ComptimeFieldCustomAttributeEnumerator : IEnumerator<Variant>, IDisposable
{
int32 mTypeId;
int32 mFieldIdx;
int32 mAttrIdx;
Variant mTargetAttr;
public this(int32 typeId, int32 fieldIdx)
{
mTypeId = typeId;
mFieldIdx = fieldIdx;
mAttrIdx = -1;
mTargetAttr = default;
}
public Variant Current
{
get
{
return mTargetAttr;
}
}
public bool MoveNext() mut
{
let attrType = Type.[Friend]Comptime_Field_GetCustomAttributeType(mTypeId, mFieldIdx, ++mAttrIdx);
if (attrType != null)
{
mTargetAttr.Dispose();
void* data = Variant.Alloc(attrType, out mTargetAttr);
if (Type.[Friend]Comptime_Field_GetCustomAttribute(mTypeId, mFieldIdx, mAttrIdx, data))
return true;
}
return false;
}
public void Dispose() mut
{
mTargetAttr.Dispose();
}
public Result<Variant> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
public struct ComptimeMethodCustomAttributeEnumerator : IEnumerator<Variant>, IDisposable
{
int64 mMethodHandle;
int32 mAttrIdx;
Variant mTargetAttr;
public this(int64 methodHandle)
{
mMethodHandle = methodHandle;
mAttrIdx = -1;
mTargetAttr = default;
}
public Variant Current
{
get
{
return mTargetAttr;
}
}
public bool MoveNext() mut
{
let attrType = Type.[Friend]Comptime_Method_GetCustomAttributeType(mMethodHandle, ++mAttrIdx);
if (attrType != null)
{
mTargetAttr.Dispose();
void* data = Variant.Alloc(attrType, out mTargetAttr);
if (Type.[Friend]Comptime_Method_GetCustomAttribute(mMethodHandle, mAttrIdx, data))
return true;
}
return false;
}
public void Dispose() mut
{
mTargetAttr.Dispose();
}
public Result<Variant> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
public struct CustomAttributeEnumerator<T> : IEnumerator<T>
{
void* mData;
int32 mAttrIdx;
uint8 mCount;
T mTargetAttr;
public this(void* inAttrData)
{
mData = inAttrData;
mData++;
mAttrIdx = 0;
mCount = mData != null ? AttributeInfo.Decode!<uint8>(mData) : 0;
mTargetAttr = ?;
}
public T Current
{
get
{
return mTargetAttr;
}
}
public bool MoveNext() mut
{
if (mAttrIdx >= mCount || mData == null)
return false;
void* endPtr = null;
TypeId typeId = 0;
while (true)
{
void* startPtr = mData;
var len = AttributeInfo.Decode!<uint16>(mData);
endPtr = (uint8*)startPtr + len;
typeId = AttributeInfo.Decode!<TypeId>(mData);
if (typeId != typeof(T).TypeId)
{
mAttrIdx++;
if (mAttrIdx >= mCount)
return false;
mData = endPtr;
continue;
}
break;
}
var methodIdx = AttributeInfo.Decode!<uint16>(mData);
Type attrType = Type.[Friend]GetType(typeId);
TypeInstance attrTypeInst = attrType as TypeInstance;
MethodInfo methodInfo = .(attrTypeInst, attrTypeInst.[Friend]mMethodDataPtr + methodIdx);
Object[] args = scope Object[methodInfo.[Friend]mData.mMethodData.mParamCount];
int argIdx = 0;
while (mData < endPtr)
{
var attrDataType = AttributeInfo.Decode!<TypeCode>(mData);
switch (attrDataType)
{
case .Int8,
.UInt8,
.Char8,
.Boolean:
let attrData = AttributeInfo.Decode!<int8>(mData);
args[argIdx] = scope:: box attrData;
case .Int16,
.UInt16,
.Char16:
let attrData = AttributeInfo.Decode!<int16>(mData);
args[argIdx] = scope:: box attrData;
case .Int32,
.UInt32,
.Char32:
let attrData = AttributeInfo.Decode!<int32>(mData);
args[argIdx] = scope:: box attrData;
case .Float:
let attrData = AttributeInfo.Decode!<float>(mData);
args[argIdx] = scope:: box attrData;
case .Int64,
.UInt64,
.Double:
let attrData = AttributeInfo.Decode!<int64>(mData);
args[argIdx] = scope:: box attrData;
case (TypeCode)typeof(TypeCode).MaxValue + 8: //BfConstType_TypeOf
let argTypeId = AttributeInfo.Decode!<int32>(mData);
args[argIdx] = Type.[Friend]GetType((.)argTypeId);
case (TypeCode)255:
let stringId = AttributeInfo.Decode!<int32>(mData);
String str = String.[Friend]sIdStringLiterals[stringId];
args[argIdx] = str;
default:
Runtime.FatalError("Not handled");
}
argIdx++;
}
if (methodInfo.Invoke(&mTargetAttr, params args) case .Ok(var val))
val.Dispose();
mAttrIdx++;
return true;
}
public void Dispose()
{
}
public Result<T> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
public struct ComptimeTypeCustomAttributeEnumerator<T> : IEnumerator<T>
{
int32 mTypeId;
int32 mAttrIdx;
T mTargetAttr;
public this(int32 typeId)
{
mTypeId = typeId;
mAttrIdx = -1;
mTargetAttr = ?;
}
public T Current
{
get
{
return mTargetAttr;
}
}
public bool MoveNext() mut
{
Type attrType = null;
repeat
{
attrType = Type.[Friend]Comptime_Type_GetCustomAttributeType(mTypeId, ++mAttrIdx);
if (attrType == typeof(T))
{
if (Type.[Friend]Comptime_Type_GetCustomAttribute(mTypeId, mAttrIdx, &mTargetAttr))
return true;
}
} while (attrType != null);
return false;
}
public void Dispose()
{
}
public Result<T> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
public struct ComptimeFieldCustomAttributeEnumerator<T> : IEnumerator<T>
{
int32 mTypeId;
int32 mFieldIdx;
int32 mAttrIdx;
T mTargetAttr;
public this(int32 typeId, int32 fieldIdx)
{
mTypeId = typeId;
mFieldIdx = fieldIdx;
mAttrIdx = -1;
mTargetAttr = ?;
}
public T Current
{
get
{
return mTargetAttr;
}
}
public bool MoveNext() mut
{
Type attrType = null;
repeat
{
attrType = Type.[Friend]Comptime_Field_GetCustomAttributeType(mTypeId, mFieldIdx, ++mAttrIdx);
if (attrType == typeof(T))
{
if (Type.[Friend]Comptime_Field_GetCustomAttribute(mTypeId, mFieldIdx, mAttrIdx, &mTargetAttr))
return true;
}
} while (attrType != null);
return false;
}
public void Dispose()
{
}
public Result<T> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
public struct ComptimeMethodCustomAttributeEnumerator<T> : IEnumerator<T>
{
int64 mMethodHandle;
int32 mAttrIdx;
T mTargetAttr;
public this(int64 methodHandle)
{
mMethodHandle = methodHandle;
mAttrIdx = -1;
mTargetAttr = ?;
}
public T Current
{
get
{
return mTargetAttr;
}
}
public bool MoveNext() mut
{
Type attrType = null;
repeat
{
attrType = Type.[Friend]Comptime_Method_GetCustomAttributeType(mMethodHandle, ++mAttrIdx);
if (attrType == typeof(T))
{
if (Type.[Friend]Comptime_Method_GetCustomAttribute(mMethodHandle, mAttrIdx, &mTargetAttr))
return true;
}
} while (attrType != null);
return false;
}
public void Dispose()
{
}
public Result<T> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
}
}