mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Improved generic param reflection in comptime
This commit is contained in:
parent
157d3f90e5
commit
26506efc1e
9 changed files with 143 additions and 19 deletions
|
@ -490,6 +490,7 @@ namespace System
|
||||||
|
|
||||||
static extern Type Comptime_GetTypeById(int32 typeId);
|
static extern Type Comptime_GetTypeById(int32 typeId);
|
||||||
static extern Type Comptime_GetTypeByName(StringView name);
|
static extern Type Comptime_GetTypeByName(StringView name);
|
||||||
|
static extern String Comptime_Type_ToString(int32 typeId);
|
||||||
static extern Type Comptime_GetSpecializedType(Type unspecializedType, Span<Type> typeArgs);
|
static extern Type Comptime_GetSpecializedType(Type unspecializedType, Span<Type> typeArgs);
|
||||||
static extern bool Comptime_Type_GetCustomAttribute(int32 typeId, int32 attributeId, void* dataPtr);
|
static extern bool Comptime_Type_GetCustomAttribute(int32 typeId, int32 attributeId, void* dataPtr);
|
||||||
static extern int32 Comptime_GetMethodCount(int32 typeId);
|
static extern int32 Comptime_GetMethodCount(int32 typeId);
|
||||||
|
@ -556,6 +557,12 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ComptimeToString(String strBuffer)
|
||||||
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
strBuffer.Append(Comptime_Type_ToString((.)mTypeId));
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void GetFullName(String strBuffer)
|
public virtual void GetFullName(String strBuffer)
|
||||||
{
|
{
|
||||||
GetBasicName(strBuffer);
|
GetBasicName(strBuffer);
|
||||||
|
@ -1285,6 +1292,23 @@ namespace System.Reflection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Ordered, AlwaysInclude(AssumeInstantiated=true)]
|
||||||
|
class GenericParamType : Type
|
||||||
|
{
|
||||||
|
public override void GetName(String strBuffer)
|
||||||
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
this.[Friend]ComptimeToString(strBuffer);
|
||||||
|
else
|
||||||
|
strBuffer.Append("$GenericParam");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void GetFullName(String strBuffer)
|
||||||
|
{
|
||||||
|
GetName(strBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum TypeFlags : uint32
|
public enum TypeFlags : uint32
|
||||||
{
|
{
|
||||||
UnspecializedGeneric = 0x0001,
|
UnspecializedGeneric = 0x0001,
|
||||||
|
|
|
@ -482,6 +482,7 @@ namespace System
|
||||||
|
|
||||||
static extern Type Comptime_GetTypeById(int32 typeId);
|
static extern Type Comptime_GetTypeById(int32 typeId);
|
||||||
static extern Type Comptime_GetTypeByName(StringView name);
|
static extern Type Comptime_GetTypeByName(StringView name);
|
||||||
|
static extern String Comptime_Type_ToString(int32 typeId);
|
||||||
static extern Type Comptime_GetSpecializedType(Type unspecializedType, Span<Type> typeArgs);
|
static extern Type Comptime_GetSpecializedType(Type unspecializedType, Span<Type> typeArgs);
|
||||||
static extern bool Comptime_Type_GetCustomAttribute(int32 typeId, int32 attributeId, void* dataPtr);
|
static extern bool Comptime_Type_GetCustomAttribute(int32 typeId, int32 attributeId, void* dataPtr);
|
||||||
static extern int32 Comptime_GetMethodCount(int32 typeId);
|
static extern int32 Comptime_GetMethodCount(int32 typeId);
|
||||||
|
@ -548,6 +549,12 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ComptimeToString(String strBuffer)
|
||||||
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
strBuffer.Append(Comptime_Type_ToString((.)mTypeId));
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void GetFullName(String strBuffer)
|
public virtual void GetFullName(String strBuffer)
|
||||||
{
|
{
|
||||||
GetBasicName(strBuffer);
|
GetBasicName(strBuffer);
|
||||||
|
@ -1261,6 +1268,23 @@ namespace System.Reflection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Ordered, AlwaysInclude(AssumeInstantiated=true)]
|
||||||
|
class GenericParamType : Type
|
||||||
|
{
|
||||||
|
public override void GetName(String strBuffer)
|
||||||
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
this.[Friend]ComptimeToString(strBuffer);
|
||||||
|
else
|
||||||
|
strBuffer.Append("$GenericParam");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void GetFullName(String strBuffer)
|
||||||
|
{
|
||||||
|
GetName(strBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum TypeFlags : uint32
|
public enum TypeFlags : uint32
|
||||||
{
|
{
|
||||||
UnspecializedGeneric = 0x0001,
|
UnspecializedGeneric = 0x0001,
|
||||||
|
|
|
@ -439,6 +439,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mPointerTypeDef = NULL;
|
mPointerTypeDef = NULL;
|
||||||
mReflectTypeIdTypeDef = NULL;
|
mReflectTypeIdTypeDef = NULL;
|
||||||
mReflectArrayType = NULL;
|
mReflectArrayType = NULL;
|
||||||
|
mReflectGenericParamType = NULL;
|
||||||
mReflectFieldDataDef = NULL;
|
mReflectFieldDataDef = NULL;
|
||||||
mReflectFieldSplatDataDef = NULL;
|
mReflectFieldSplatDataDef = NULL;
|
||||||
mReflectMethodDataDef = NULL;
|
mReflectMethodDataDef = NULL;
|
||||||
|
@ -1345,6 +1346,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
|
||||||
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectSpecializedGenericType));
|
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectSpecializedGenericType));
|
||||||
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectUnspecializedGenericType));
|
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectUnspecializedGenericType));
|
||||||
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectArrayType));
|
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectArrayType));
|
||||||
|
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectGenericParamType));
|
||||||
|
|
||||||
SmallVector<BfIRValue, 256> typeDataVector;
|
SmallVector<BfIRValue, 256> typeDataVector;
|
||||||
for (auto type : vdataTypeList)
|
for (auto type : vdataTypeList)
|
||||||
|
@ -6835,6 +6837,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mPointerTypeDef = _GetRequiredType("System.Pointer", 0);
|
mPointerTypeDef = _GetRequiredType("System.Pointer", 0);
|
||||||
mReflectTypeIdTypeDef = _GetRequiredType("System.Reflection.TypeId");
|
mReflectTypeIdTypeDef = _GetRequiredType("System.Reflection.TypeId");
|
||||||
mReflectArrayType = _GetRequiredType("System.Reflection.ArrayType");
|
mReflectArrayType = _GetRequiredType("System.Reflection.ArrayType");
|
||||||
|
mReflectGenericParamType = _GetRequiredType("System.Reflection.GenericParamType");
|
||||||
mReflectFieldDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldData");
|
mReflectFieldDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldData");
|
||||||
mReflectFieldSplatDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldSplatData");
|
mReflectFieldSplatDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldSplatData");
|
||||||
mReflectMethodDataDef = _GetRequiredType("System.Reflection.TypeInstance.MethodData");
|
mReflectMethodDataDef = _GetRequiredType("System.Reflection.TypeInstance.MethodData");
|
||||||
|
|
|
@ -398,6 +398,7 @@ public:
|
||||||
BfTypeDef* mPointerTypeDef;
|
BfTypeDef* mPointerTypeDef;
|
||||||
BfTypeDef* mReflectTypeIdTypeDef;
|
BfTypeDef* mReflectTypeIdTypeDef;
|
||||||
BfTypeDef* mReflectArrayType;
|
BfTypeDef* mReflectArrayType;
|
||||||
|
BfTypeDef* mReflectGenericParamType;
|
||||||
BfTypeDef* mReflectFieldDataDef;
|
BfTypeDef* mReflectFieldDataDef;
|
||||||
BfTypeDef* mReflectFieldSplatDataDef;
|
BfTypeDef* mReflectFieldSplatDataDef;
|
||||||
BfTypeDef* mReflectMethodDataDef;
|
BfTypeDef* mReflectMethodDataDef;
|
||||||
|
|
|
@ -10593,15 +10593,8 @@ void BfExprEvaluator::Visit(BfTypeOfExpression* typeOfExpr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((type->IsGenericParam()) && (!mModule->mIsComptimeModule))
|
|
||||||
{
|
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(typeType)), typeType);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
|
mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
|
||||||
mResult = BfTypedValue(mModule->CreateTypeDataRef(type), typeType);
|
mResult = BfTypedValue(mModule->CreateTypeDataRef(type), typeType);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName)
|
bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName)
|
||||||
|
|
|
@ -5396,12 +5396,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
typeDataSource = ResolveTypeDef(mCompiler->mReflectSizedArrayType)->ToTypeInstance();
|
typeDataSource = ResolveTypeDef(mCompiler->mReflectSizedArrayType)->ToTypeInstance();
|
||||||
else if (type->IsConstExprValue())
|
else if (type->IsConstExprValue())
|
||||||
typeDataSource = ResolveTypeDef(mCompiler->mReflectConstExprType)->ToTypeInstance();
|
typeDataSource = ResolveTypeDef(mCompiler->mReflectConstExprType)->ToTypeInstance();
|
||||||
|
else if (type->IsGenericParam())
|
||||||
|
{
|
||||||
|
typeFlags |= BfTypeFlags_GenericParam;
|
||||||
|
typeDataSource = ResolveTypeDef(mCompiler->mReflectGenericParamType)->ToTypeInstance();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
typeDataSource = mContext->mBfTypeType;
|
typeDataSource = mContext->mBfTypeType;
|
||||||
|
|
||||||
if (type->IsGenericParam())
|
|
||||||
typeFlags |= BfTypeFlags_GenericParam;
|
|
||||||
|
|
||||||
if ((!mTypeDataRefs.ContainsKey(typeDataSource)) && (typeDataSource != type))
|
if ((!mTypeDataRefs.ContainsKey(typeDataSource)) && (typeDataSource != type))
|
||||||
{
|
{
|
||||||
CreateTypeData(typeDataSource, usedStringIdMap, false, true, needsTypeNames, true);
|
CreateTypeData(typeDataSource, usedStringIdMap, false, true, needsTypeNames, true);
|
||||||
|
@ -5636,6 +5638,22 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize);
|
mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize);
|
||||||
typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType));
|
typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType));
|
||||||
}
|
}
|
||||||
|
else if (type->IsGenericParam())
|
||||||
|
{
|
||||||
|
auto genericParamType = (BfGenericParamType*)type;
|
||||||
|
SizedArray<BfIRValue, 3> genericParamTypeDataParms =
|
||||||
|
{
|
||||||
|
typeData
|
||||||
|
};
|
||||||
|
|
||||||
|
auto reflectGenericParamType = ResolveTypeDef(mCompiler->mReflectGenericParamType)->ToTypeInstance();
|
||||||
|
FixConstValueParams(reflectGenericParamType, genericParamTypeDataParms);
|
||||||
|
auto genericParamTypeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectGenericParamType, BfIRPopulateType_Full), genericParamTypeDataParms);
|
||||||
|
typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectGenericParamType), true,
|
||||||
|
BfIRLinkageType_External, genericParamTypeData, typeDataName);
|
||||||
|
mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize);
|
||||||
|
typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(mContext->mBfTypeType), true,
|
typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(mContext->mBfTypeType), true,
|
||||||
|
|
|
@ -2913,6 +2913,9 @@ CeContext::CeContext()
|
||||||
mCurFrame = NULL;
|
mCurFrame = NULL;
|
||||||
mCurModule = NULL;
|
mCurModule = NULL;
|
||||||
mCurMethodInstance = NULL;
|
mCurMethodInstance = NULL;
|
||||||
|
mCallerMethodInstance = NULL;
|
||||||
|
mCallerTypeInstance = NULL;
|
||||||
|
mCallerActiveTypeDef = NULL;
|
||||||
mCurExpectingType = NULL;
|
mCurExpectingType = NULL;
|
||||||
mCurEmitContext = NULL;
|
mCurEmitContext = NULL;
|
||||||
}
|
}
|
||||||
|
@ -2983,18 +2986,20 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
|
||||||
err += " ";
|
err += " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
auto contextMethodInstance = mCurModule->mCurMethodInstance;
|
auto contextMethodInstance = mCallerMethodInstance;
|
||||||
|
auto contextTypeInstance = mCallerTypeInstance;
|
||||||
if (stackIdx > 1)
|
if (stackIdx > 1)
|
||||||
{
|
{
|
||||||
auto func = mCallStack[stackIdx - 1].mFunction;
|
auto func = mCallStack[stackIdx - 1].mFunction;
|
||||||
contextMethodInstance = func->mCeFunctionInfo->mMethodInstance;
|
contextMethodInstance = func->mCeFunctionInfo->mMethodInstance;
|
||||||
|
contextTypeInstance = contextMethodInstance->GetOwner();
|
||||||
}
|
}
|
||||||
|
|
||||||
err += StrFormat("in comptime ");
|
err += StrFormat("in comptime ");
|
||||||
|
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, (contextMethodInstance != NULL) ? contextMethodInstance->GetOwner() : NULL);
|
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, contextTypeInstance);
|
||||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, contextMethodInstance);
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, contextMethodInstance);
|
||||||
|
|
||||||
if (ceFunction->mMethodInstance != NULL)
|
if (ceFunction->mMethodInstance != NULL)
|
||||||
|
@ -3033,7 +3038,7 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
|
||||||
void CeContext::FixProjectRelativePath(StringImpl& path)
|
void CeContext::FixProjectRelativePath(StringImpl& path)
|
||||||
{
|
{
|
||||||
BfProject* activeProject = NULL;
|
BfProject* activeProject = NULL;
|
||||||
auto activeTypeDef = mCurModule->GetActiveTypeDef();
|
auto activeTypeDef = mCallerActiveTypeDef;
|
||||||
if (activeTypeDef != NULL)
|
if (activeTypeDef != NULL)
|
||||||
activeProject = activeTypeDef->mProject;
|
activeProject = activeTypeDef->mProject;
|
||||||
if (activeProject != NULL)
|
if (activeProject != NULL)
|
||||||
|
@ -4064,8 +4069,14 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
SetAndRestoreValue<BfAstNode*> prevTargetSrc(mCurTargetSrc, targetSrc);
|
SetAndRestoreValue<BfAstNode*> prevTargetSrc(mCurTargetSrc, targetSrc);
|
||||||
SetAndRestoreValue<BfModule*> prevModule(mCurModule, module);
|
SetAndRestoreValue<BfModule*> prevModule(mCurModule, module);
|
||||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, methodInstance);
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, methodInstance);
|
||||||
|
SetAndRestoreValue<BfMethodInstance*> prevCallerMethodInstance(mCallerMethodInstance, module->mCurMethodInstance);
|
||||||
|
SetAndRestoreValue<BfTypeInstance*> prevCallerTypeInstance(mCallerTypeInstance, module->mCurTypeInstance);
|
||||||
|
SetAndRestoreValue<BfTypeDef*> prevCallerActiveTypeDef(mCallerActiveTypeDef, module->GetActiveTypeDef());
|
||||||
SetAndRestoreValue<BfType*> prevExpectingType(mCurExpectingType, expectingType);
|
SetAndRestoreValue<BfType*> prevExpectingType(mCurExpectingType, expectingType);
|
||||||
|
|
||||||
|
SetAndRestoreValue<BfMethodInstance*> moduleCurMethodInstance(module->mCurMethodInstance, methodInstance);
|
||||||
|
SetAndRestoreValue<BfTypeInstance*> moduleCurTypeInstance(module->mCurTypeInstance, methodInstance->GetOwner());
|
||||||
|
|
||||||
SetAndRestoreValue<int> prevCurExecuteId(mCurModule->mCompiler->mCurCEExecuteId, mCeMachine->mExecuteId);
|
SetAndRestoreValue<int> prevCurExecuteId(mCurModule->mCompiler->mCurCEExecuteId, mCeMachine->mExecuteId);
|
||||||
|
|
||||||
// Reentrancy may occur as methods need defining
|
// Reentrancy may occur as methods need defining
|
||||||
|
@ -4854,6 +4865,23 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
_FixVariables();
|
_FixVariables();
|
||||||
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
|
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
|
||||||
}
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_Type_ToString)
|
||||||
|
{
|
||||||
|
int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
|
||||||
|
|
||||||
|
BfType* type = GetBfType(typeId);
|
||||||
|
bool success = false;
|
||||||
|
if (type == NULL)
|
||||||
|
{
|
||||||
|
_Fail("Invalid type");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, mCallerMethodInstance);
|
||||||
|
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, mCallerTypeInstance);
|
||||||
|
CeSetAddrVal(stackPtr + 0, GetString(mCeMachine->mCeModule->TypeToString(type)), ptrSize);
|
||||||
|
_FixVariables();
|
||||||
|
}
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_Type_GetCustomAttribute)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_Type_GetCustomAttribute)
|
||||||
{
|
{
|
||||||
int32 typeId = *(int32*)((uint8*)stackPtr + 1);
|
int32 typeId = *(int32*)((uint8*)stackPtr + 1);
|
||||||
|
@ -7786,6 +7814,10 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
|
||||||
{
|
{
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_GetReflectSpecializedType;
|
ceFunction->mFunctionKind = CeFunctionKind_GetReflectSpecializedType;
|
||||||
}
|
}
|
||||||
|
else if (methodDef->mName == "Comptime_Type_ToString")
|
||||||
|
{
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_Type_ToString;
|
||||||
|
}
|
||||||
else if (methodDef->mName == "Comptime_Type_GetCustomAttribute")
|
else if (methodDef->mName == "Comptime_Type_GetCustomAttribute")
|
||||||
{
|
{
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Type_GetCustomAttribute;
|
ceFunction->mFunctionKind = CeFunctionKind_Type_GetCustomAttribute;
|
||||||
|
|
|
@ -324,6 +324,7 @@ enum CeFunctionKind
|
||||||
CeFunctionKind_GetReflectTypeById,
|
CeFunctionKind_GetReflectTypeById,
|
||||||
CeFunctionKind_GetReflectTypeByName,
|
CeFunctionKind_GetReflectTypeByName,
|
||||||
CeFunctionKind_GetReflectSpecializedType,
|
CeFunctionKind_GetReflectSpecializedType,
|
||||||
|
CeFunctionKind_Type_ToString,
|
||||||
CeFunctionKind_Type_GetCustomAttribute,
|
CeFunctionKind_Type_GetCustomAttribute,
|
||||||
CeFunctionKind_GetMethodCount,
|
CeFunctionKind_GetMethodCount,
|
||||||
CeFunctionKind_GetMethod,
|
CeFunctionKind_GetMethod,
|
||||||
|
@ -867,6 +868,9 @@ public:
|
||||||
Dictionary<int, CeInternalData*> mInternalDataMap;
|
Dictionary<int, CeInternalData*> mInternalDataMap;
|
||||||
int mCurHandleId;
|
int mCurHandleId;
|
||||||
|
|
||||||
|
BfMethodInstance* mCallerMethodInstance;
|
||||||
|
BfTypeInstance* mCallerTypeInstance;
|
||||||
|
BfTypeDef* mCallerActiveTypeDef;
|
||||||
BfMethodInstance* mCurMethodInstance;
|
BfMethodInstance* mCurMethodInstance;
|
||||||
BfType* mCurExpectingType;
|
BfType* mCurExpectingType;
|
||||||
BfAstNode* mCurTargetSrc;
|
BfAstNode* mCurTargetSrc;
|
||||||
|
|
|
@ -405,6 +405,25 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct GetTupleField<TTuple, C> where C : const int
|
||||||
|
{
|
||||||
|
public typealias Type = comptype(GetTupleFieldType(typeof(TTuple), C));
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
private static Type GetTupleFieldType(Type type, int index)
|
||||||
|
{
|
||||||
|
if (type.IsGenericParam)
|
||||||
|
{
|
||||||
|
Compiler.Assert(type.IsGenericParam);
|
||||||
|
String tName = type.GetFullName(.. scope .());
|
||||||
|
Compiler.Assert(tName == "TTuple");
|
||||||
|
return typeof(var);
|
||||||
|
}
|
||||||
|
Compiler.Assert(type.IsTuple);
|
||||||
|
return type.GetField(index).Get().FieldType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -468,6 +487,12 @@ namespace Tests
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
Test.Assert(idx == 2);
|
Test.Assert(idx == 2);
|
||||||
|
|
||||||
|
var tuple = ((int16)1, 2.3f);
|
||||||
|
GetTupleField<decltype(tuple), const 0>.Type tupType0;
|
||||||
|
GetTupleField<decltype(tuple), const 1>.Type tupType1;
|
||||||
|
Test.Assert(typeof(decltype(tupType0)) == typeof(int16));
|
||||||
|
Test.Assert(typeof(decltype(tupType1)) == typeof(float));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue