mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Expanding support for params
in delegates, params
tuple support
This commit is contained in:
parent
4b660b2314
commit
421cace017
11 changed files with 203 additions and 59 deletions
5
BeefLibs/corlib/src/Tuple.bf
Normal file
5
BeefLibs/corlib/src/Tuple.bf
Normal file
|
@ -0,0 +1,5 @@
|
|||
namespace System;
|
||||
|
||||
struct Tuple
|
||||
{
|
||||
}
|
|
@ -551,10 +551,12 @@ protected:
|
|||
if ((mAllocSizeAndFlags & AttrFlags) == StrPtrFlag)
|
||||
{
|
||||
// It's a reference
|
||||
char* newPtr = AllocPtr(this->mLength);
|
||||
memcpy(newPtr, this->mPtr, this->mLength + 1);
|
||||
int allocSize = (int)BF_MAX(GetAllocSize(), this->mLength + 1);
|
||||
char* newPtr = AllocPtr(allocSize);
|
||||
memcpy(newPtr, this->mPtr, this->mLength);
|
||||
newPtr[this->mLength] = 0;
|
||||
this->mPtr = newPtr;
|
||||
mAllocSizeAndFlags = this->mLength | DynAllocFlag | StrPtrFlag;
|
||||
mAllocSizeAndFlags = allocSize | DynAllocFlag | StrPtrFlag;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -213,6 +213,11 @@ namespace System
|
|||
public static extern bool Equals<T>(T val1, T val2);
|
||||
}
|
||||
|
||||
struct Tuple
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct Function : int
|
||||
{
|
||||
|
||||
|
|
|
@ -478,6 +478,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
|||
mTypeTypeDef = NULL;
|
||||
mUnboundAttributeTypeDef = NULL;
|
||||
mValueTypeTypeDef = NULL;
|
||||
mTupleTypeDef = NULL;
|
||||
mResultTypeDef = NULL;
|
||||
mObsoleteAttributeTypeDef = NULL;
|
||||
mErrorAttributeTypeDef = NULL;
|
||||
|
@ -7334,6 +7335,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
mTypeTypeDef = _GetRequiredType("System.Type");
|
||||
mUnboundAttributeTypeDef = _GetRequiredType("System.UnboundAttribute");
|
||||
mValueTypeTypeDef = _GetRequiredType("System.ValueType");
|
||||
mTupleTypeDef = _GetRequiredType("System.Tuple");
|
||||
mObsoleteAttributeTypeDef = _GetRequiredType("System.ObsoleteAttribute");
|
||||
mErrorAttributeTypeDef = _GetRequiredType("System.ErrorAttribute");
|
||||
mWarnAttributeTypeDef = _GetRequiredType("System.WarnAttribute");
|
||||
|
|
|
@ -379,6 +379,7 @@ public:
|
|||
BfTypeDef* mTypeTypeDeclDef;
|
||||
BfTypeDef* mTypeTypeDef;
|
||||
BfTypeDef* mValueTypeTypeDef;
|
||||
BfTypeDef* mTupleTypeDef;
|
||||
BfTypeDef* mResultTypeDef;
|
||||
BfTypeDef* mGCTypeDef;
|
||||
BfTypeDef* mGenericIEnumerableTypeDef;
|
||||
|
|
|
@ -14741,30 +14741,19 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
|||
|
||||
if (invokeMethodInstance != NULL)
|
||||
{
|
||||
for (int paramIdx = 0; paramIdx < (int)invokeMethodInstance->mMethodDef->mParams.size(); paramIdx++)
|
||||
for (int paramIdx = 0; paramIdx < (int)invokeMethodInstance->GetParamCount(); paramIdx++)
|
||||
{
|
||||
auto invokeParamDef = invokeMethodInstance->mMethodDef->mParams[paramIdx];
|
||||
|
||||
BfParameterDef* paramDef = new BfParameterDef();
|
||||
paramDef->mParamDeclaration = tempParamDecls.Alloc();
|
||||
BfAstNode::Zero(paramDef->mParamDeclaration);
|
||||
|
||||
BfLocalVariable* localVar = new BfLocalVariable();
|
||||
BfLocalVariable* localVar = new BfLocalVariable();
|
||||
if (paramIdx < (int)lambdaBindExpr->mParams.size())
|
||||
{
|
||||
localVar->mName = lambdaBindExpr->mParams[paramIdx]->ToString();
|
||||
localVar->mNameNode = lambdaBindExpr->mParams[paramIdx];
|
||||
paramDef->mParamDeclaration->mNameNode = lambdaBindExpr->mParams[paramIdx];
|
||||
localVar->mNameNode = lambdaBindExpr->mParams[paramIdx];
|
||||
}
|
||||
else
|
||||
{
|
||||
mModule->AssertErrorState();
|
||||
localVar->mName = invokeParamDef->mName;
|
||||
paramDef->mParamDeclaration->mNameNode = NULL;
|
||||
}
|
||||
paramDef->mName = localVar->mName;
|
||||
methodDef->mParams.push_back(paramDef);
|
||||
|
||||
localVar->mName = invokeMethodInstance->GetParamName(paramIdx);
|
||||
}
|
||||
localVar->mResolvedType = invokeMethodInstance->GetParamType(paramIdx);
|
||||
mModule->PopulateType(localVar->mResolvedType);
|
||||
localVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
|
||||
|
@ -14773,15 +14762,41 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
|||
auto rootMethodState = methodState.GetRootMethodState();
|
||||
localVar->mLocalVarId = rootMethodState->mCurLocalVarId++;
|
||||
|
||||
mModule->DoAddLocalVariable(localVar);
|
||||
mModule->DoAddLocalVariable(localVar);
|
||||
|
||||
if (autoComplete != NULL)
|
||||
autoComplete->CheckLocalDef(BfNodeDynCast<BfIdentifierNode>(paramDef->mParamDeclaration->mNameNode), methodState.mLocals.back());
|
||||
auto resolvePassData = mModule->mCompiler->mResolvePassData;
|
||||
if (resolvePassData != NULL)
|
||||
resolvePassData->HandleLocalReference(BfNodeDynCast<BfIdentifierNode>(paramDef->mParamDeclaration->mNameNode), mModule->mCurTypeInstance->mTypeDef,
|
||||
resolvePassData->HandleLocalReference(BfNodeDynCast<BfIdentifierNode>(localVar->mNameNode), mModule->mCurTypeInstance->mTypeDef,
|
||||
mModule->mCurMethodInstance->mMethodDef, localVar->mLocalVarId);
|
||||
}
|
||||
|
||||
for (int paramIdx = 0; paramIdx < (int)invokeMethodInstance->mMethodDef->mParams.size(); paramIdx++)
|
||||
{
|
||||
auto invokeParamDef = invokeMethodInstance->mMethodDef->mParams[paramIdx];
|
||||
|
||||
BfParameterDef* paramDef = new BfParameterDef();
|
||||
paramDef->mParamDeclaration = tempParamDecls.Alloc();
|
||||
BfAstNode::Zero(paramDef->mParamDeclaration);
|
||||
paramDef->mTypeRef = invokeParamDef->mTypeRef;
|
||||
paramDef->mParamKind = invokeParamDef->mParamKind;
|
||||
|
||||
if ((paramIdx < (int)lambdaBindExpr->mParams.size()) && (invokeMethodInstance->GetParamKind(paramIdx) != BfParamKind_DelegateParam))
|
||||
{
|
||||
//TODO: Not always correct if we have a 'params'
|
||||
paramDef->mParamDeclaration->mNameNode = lambdaBindExpr->mParams[paramIdx];
|
||||
paramDef->mName = paramDef->mParamDeclaration->mNameNode->ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
paramDef->mParamDeclaration->mNameNode = NULL;
|
||||
paramDef->mName = invokeParamDef->mName;
|
||||
}
|
||||
|
||||
methodDef->mParams.push_back(paramDef);
|
||||
|
||||
if (autoComplete != NULL)
|
||||
autoComplete->CheckLocalDef(BfNodeDynCast<BfIdentifierNode>(paramDef->mParamDeclaration->mNameNode), methodState.mLocals.back());
|
||||
}
|
||||
}
|
||||
|
||||
bool isAutocomplete = mModule->mCompiler->IsAutocomplete();
|
||||
|
@ -24091,12 +24106,17 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
|
|||
rightTypedValueExpr.mRefNode = opToken;
|
||||
|
||||
auto valueTypeEmpty = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mBaseType->mBaseType), {});
|
||||
|
||||
SizedArray<BfIRValue, 8> tupleEmptyMembers;
|
||||
tupleEmptyMembers.Add(valueTypeEmpty);
|
||||
auto tupleTypeEmpty = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(mModule->ResolveTypeDef(mModule->mCompiler->mTupleTypeDef)), tupleEmptyMembers);
|
||||
|
||||
SizedArray<BfIRValue, 8> enumMembers;
|
||||
enumMembers.Add(valueTypeEmpty);
|
||||
auto enumValue = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mBaseType), enumMembers);
|
||||
|
||||
SizedArray<BfIRValue, 8> tupleMembers;
|
||||
tupleMembers.Add(valueTypeEmpty);
|
||||
tupleMembers.Add(tupleTypeEmpty);
|
||||
tupleMembers.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1));
|
||||
auto tupleValue = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mFieldInstances[0].mResolvedType), tupleMembers);
|
||||
|
||||
|
|
|
@ -3617,25 +3617,22 @@ void BfModule::FatalError(const StringImpl& error, const char* file, int line, i
|
|||
BfpSystem_FatalError(fullError.c_str(), "FATAL MODULE ERROR");
|
||||
}
|
||||
|
||||
void BfModule::FatalError(const StringImpl& error, BfAstNode* refNode)
|
||||
void BfModule::FatalError(const StringImpl& error, BfFailHandleKind failHandleKind)
|
||||
{
|
||||
if (refNode != NULL)
|
||||
{
|
||||
auto parser = refNode->GetParserData();
|
||||
if (parser != NULL)
|
||||
{
|
||||
int line = -1;
|
||||
int lineChar = -1;
|
||||
parser->GetLineCharAtIdx(refNode->mSrcStart, line, lineChar);
|
||||
if (line != -1)
|
||||
FatalError(error, parser->mFileName.c_str(), line, lineChar);
|
||||
}
|
||||
}
|
||||
FatalError(error);
|
||||
if (failHandleKind == BfFailHandleKind_Normal)
|
||||
FatalError(error);
|
||||
else if (failHandleKind == BfFailHandleKind_Soft)
|
||||
InternalError(error);
|
||||
}
|
||||
|
||||
void BfModule::InternalError(const StringImpl& error, BfAstNode* refNode, const char* file, int line)
|
||||
{
|
||||
static bool isInside = false;
|
||||
if (isInside)
|
||||
return;
|
||||
|
||||
isInside = true;
|
||||
|
||||
String fullError = error;
|
||||
|
||||
if (file != NULL)
|
||||
|
@ -3652,6 +3649,8 @@ void BfModule::InternalError(const StringImpl& error, BfAstNode* refNode, const
|
|||
fullError += StrFormat("\nSource Location: %s:%d", mCurFilePosition.mFileInstance->mParser->mFileName.c_str(), mCurFilePosition.mCurLine + 1);
|
||||
|
||||
Fail(String("INTERNAL ERROR: ") + fullError, refNode);
|
||||
|
||||
isInside = false;
|
||||
}
|
||||
|
||||
void BfModule::NotImpl(BfAstNode* astNode)
|
||||
|
@ -16018,6 +16017,8 @@ BfIRValue BfModule::AllocLocalVariable(BfType* type, const StringImpl& name, boo
|
|||
|
||||
void BfModule::DoAddLocalVariable(BfLocalVariable* localVar)
|
||||
{
|
||||
BF_ASSERT(localVar->mResolvedType != NULL);
|
||||
|
||||
while (localVar->mName.StartsWith('@'))
|
||||
{
|
||||
localVar->mNamePrefixCount++;
|
||||
|
@ -17064,7 +17065,7 @@ void BfModule::AssertErrorState()
|
|||
if (mCompiler->mPassInstance->HasFailed())
|
||||
return;
|
||||
|
||||
InternalError("Compiler in invalid state but AssertErrorState failed to prior error");
|
||||
InternalError("Compiler in invalid state but AssertErrorState failed to detect prior error");
|
||||
}
|
||||
|
||||
void BfModule::AssertParseErrorState()
|
||||
|
@ -20008,14 +20009,17 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
|||
{
|
||||
if (compositeVariableIdx == -1)
|
||||
{
|
||||
compositeVariableIdx = (int)mCurMethodState->mLocals.size();
|
||||
|
||||
BfLocalVariable* localVar = new BfLocalVariable();
|
||||
auto paramInst = &methodInstance->mParams[paramIdx];
|
||||
auto paramDef = methodDef->mParams[paramInst->mParamDefIdx];
|
||||
|
||||
compositeVariableIdx = (int)mCurMethodState->mLocals.size();
|
||||
BfLocalVariable* localVar = new BfLocalVariable();
|
||||
localVar->mName = paramDef->mName;
|
||||
localVar->mNamePrefixCount = paramDef->mNamePrefixCount;
|
||||
localVar->mResolvedType = ResolveTypeRef(paramDef->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_NoResolveGenericParam);
|
||||
if (paramDef->mTypeRef != NULL)
|
||||
localVar->mResolvedType = ResolveTypeRef(paramDef->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_NoResolveGenericParam);
|
||||
if (localVar->mResolvedType == NULL)
|
||||
localVar->mResolvedType = GetPrimitiveType(BfTypeCode_None);
|
||||
localVar->mCompositeCount = 0;
|
||||
DoAddLocalVariable(localVar);
|
||||
}
|
||||
|
@ -20064,9 +20068,9 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
|||
if (genericParamInstance->mTypeConstraint != NULL)
|
||||
{
|
||||
auto typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance();
|
||||
if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()) ||
|
||||
if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()) || (genericParamInstance->mTypeConstraint->IsTuple()) ||
|
||||
((typeInstConstraint != NULL) &&
|
||||
((typeInstConstraint->IsInstanceOf(mCompiler->mDelegateTypeDef)) || (typeInstConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)))))
|
||||
((typeInstConstraint->IsInstanceOf(mCompiler->mDelegateTypeDef)) || (typeInstConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)) || (typeInstConstraint->IsInstanceOf(mCompiler->mTupleTypeDef)))))
|
||||
{
|
||||
BfLocalVariable* localVar = new BfLocalVariable();
|
||||
localVar->mName = paramDef->mName;
|
||||
|
@ -24965,10 +24969,43 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
isValid = true;
|
||||
addParams = false;
|
||||
}
|
||||
else if (resolvedParamType->IsTuple())
|
||||
{
|
||||
auto tupleType = (BfTupleType*)resolvedParamType;
|
||||
PopulateType(tupleType);
|
||||
|
||||
hadDelegateParams = true;
|
||||
|
||||
// This means we copy the params from a delegate
|
||||
BfMethodParam methodParam;
|
||||
methodParam.mResolvedType = resolvedParamType;
|
||||
methodParam.mParamDefIdx = paramDefIdx;
|
||||
methodParam.mDelegateParamIdx = 0;
|
||||
auto invokeMethodInstance = methodParam.GetDelegateParamInvoke();
|
||||
for (int delegateParamIdx = 0; delegateParamIdx < tupleType->mFieldInstances.mSize; delegateParamIdx++)
|
||||
{
|
||||
auto& fieldInstance = tupleType->mFieldInstances[delegateParamIdx];
|
||||
|
||||
methodParam.mDelegateParamIdx = delegateParamIdx;
|
||||
mCurMethodInstance->mParams.Add(methodParam);
|
||||
|
||||
if (!methodInstance->IsSpecializedGenericMethod())
|
||||
AddDependency(fieldInstance.mResolvedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
|
||||
}
|
||||
isValid = true;
|
||||
addParams = false;
|
||||
}
|
||||
else if (resolvedParamType->IsGenericParam())
|
||||
{
|
||||
auto genericParamInstance = GetGenericParamInstance((BfGenericParamType*)resolvedParamType);
|
||||
if (genericParamInstance->mTypeConstraint != NULL)
|
||||
auto genericParamInstance = GetGenericParamInstance((BfGenericParamType*)resolvedParamType, false, BfFailHandleKind_Ignore);
|
||||
if (genericParamInstance == NULL)
|
||||
{
|
||||
// Delegate case with a 'params T'?
|
||||
mCurMethodInstance->mHadGenericDelegateParams = true;
|
||||
isValid = true;
|
||||
addParams = false;
|
||||
}
|
||||
else if (genericParamInstance->mTypeConstraint != NULL)
|
||||
{
|
||||
auto typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance();
|
||||
if ((genericParamInstance->mTypeConstraint->IsArray()) || (genericParamInstance->mTypeConstraint->IsSizedArray()))
|
||||
|
@ -24979,9 +25016,9 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
mCurMethodInstance->mParams.Add(methodParam);
|
||||
isValid = true;
|
||||
}
|
||||
else if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()) ||
|
||||
else if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()) || (genericParamInstance->mTypeConstraint->IsTuple()) ||
|
||||
((genericParamInstance != NULL) && (typeInstConstraint != NULL) &&
|
||||
((typeInstConstraint->IsInstanceOf(mCompiler->mDelegateTypeDef)) || (typeInstConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)))))
|
||||
((typeInstConstraint->IsInstanceOf(mCompiler->mDelegateTypeDef)) || (typeInstConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)) || (typeInstConstraint->IsInstanceOf(mCompiler->mTupleTypeDef)))))
|
||||
{
|
||||
mCurMethodInstance->mHadGenericDelegateParams = true;
|
||||
isValid = true;
|
||||
|
@ -25055,10 +25092,22 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
{
|
||||
if (usedParamDefIdx[methodParam.mParamDefIdx] > 1)
|
||||
methodParam.mDelegateParamNameCombine = true;
|
||||
BfMethodInstance* invokeMethodInstance = methodParam.GetDelegateParamInvoke();
|
||||
String paramName = invokeMethodInstance->GetParamName(methodParam.mDelegateParamIdx);
|
||||
if (usedNames.Contains(paramName))
|
||||
methodParam.mDelegateParamNameCombine = true;
|
||||
|
||||
if (methodParam.mResolvedType->IsTuple())
|
||||
{
|
||||
auto tupleType = (BfTupleType*)methodParam.mResolvedType;
|
||||
auto& fieldInstance = tupleType->mFieldInstances[methodParam.mDelegateParamIdx];
|
||||
auto paramName = fieldInstance.GetFieldDef()->mName;
|
||||
if (!usedNames.Add(paramName))
|
||||
methodParam.mDelegateParamNameCombine = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BfMethodInstance* invokeMethodInstance = methodParam.GetDelegateParamInvoke();
|
||||
String paramName = invokeMethodInstance->GetParamName(methodParam.mDelegateParamIdx);
|
||||
if (!usedNames.Add(paramName))
|
||||
methodParam.mDelegateParamNameCombine = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1617,6 +1617,7 @@ public:
|
|||
public:
|
||||
void FatalError(const StringImpl& error, const char* file = NULL, int line = -1, int column = -1);
|
||||
void FatalError(const StringImpl& error, BfAstNode* refNode);
|
||||
void FatalError(const StringImpl& error, BfFailHandleKind failHandleKind);
|
||||
void InternalError(const StringImpl& error, BfAstNode* refNode = NULL, const char* file = NULL, int line = -1);
|
||||
void NotImpl(BfAstNode* astNode);
|
||||
void AddMethodReference(const BfMethodRef& methodRef, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
|
||||
|
@ -1959,7 +1960,7 @@ public:
|
|||
BfType* ResolveGenericType(BfType* unspecializedType, BfTypeVector* typeGenericArguments, BfTypeVector* methodGenericArguments, BfType* selfType, bool allowFail = false);
|
||||
BfType* ResolveSelfType(BfType* type, BfType* selfType);
|
||||
bool IsUnboundGeneric(BfType* type);
|
||||
BfGenericParamInstance* GetGenericTypeParamInstance(int paramIdx);
|
||||
BfGenericParamInstance* GetGenericTypeParamInstance(int paramIdx, BfFailHandleKind failHandleKind = BfFailHandleKind_Normal);
|
||||
BfGenericParamInstance* GetGenericParamInstance(BfGenericParamType* type, bool checkMixinBind = false, BfFailHandleKind failHandleKind = BfFailHandleKind_Normal);
|
||||
void GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInstance*, 4>& genericParamInstance);
|
||||
BfGenericParamInstance* GetMergedGenericParamData(BfType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint);
|
||||
|
|
|
@ -4209,6 +4209,10 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
{
|
||||
baseType = ResolveTypeDef(mCompiler->mPointerTTypeDef, BfPopulateType_Data);
|
||||
}
|
||||
else if (resolvedTypeRef->IsTuple())
|
||||
{
|
||||
baseType = ResolveTypeDef(mCompiler->mTupleTypeDef, BfPopulateType_Data);
|
||||
}
|
||||
else if ((resolvedTypeRef->IsValueType()) && (typeDef != mCompiler->mValueTypeTypeDef))
|
||||
{
|
||||
baseType = ResolveTypeDef(mCompiler->mValueTypeTypeDef, BfPopulateType_Data)->ToTypeInstance();
|
||||
|
@ -9565,7 +9569,7 @@ bool BfModule::IsUnboundGeneric(BfType* type)
|
|||
return (genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0;
|
||||
}
|
||||
|
||||
BfGenericParamInstance* BfModule::GetGenericTypeParamInstance(int genericParamIdx)
|
||||
BfGenericParamInstance* BfModule::GetGenericTypeParamInstance(int genericParamIdx, BfFailHandleKind failHandleKind)
|
||||
{
|
||||
// When we're evaluating a method, make sure the params refer back to that method context
|
||||
auto curTypeInstance = mCurTypeInstance;
|
||||
|
@ -9576,8 +9580,8 @@ BfGenericParamInstance* BfModule::GetGenericTypeParamInstance(int genericParamId
|
|||
BfTypeInstance* genericTypeInst = curTypeInstance->ToGenericTypeInstance();
|
||||
|
||||
if (genericTypeInst == NULL)
|
||||
{
|
||||
FatalError("Invalid mCurTypeInstance for GetGenericTypeParamInstance");
|
||||
{
|
||||
FatalError("Invalid mCurTypeInstance for GetGenericTypeParamInstance", failHandleKind);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -9756,7 +9760,7 @@ BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* ty
|
|||
return curGenericMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx];
|
||||
}
|
||||
|
||||
return GetGenericTypeParamInstance(type->mGenericParamIdx);
|
||||
return GetGenericTypeParamInstance(type->mGenericParamIdx, failHandleKind);
|
||||
}
|
||||
|
||||
bool BfModule::ResolveTypeResult_Validate(BfAstNode* typeRef, BfType* resolvedTypeRef)
|
||||
|
|
|
@ -698,7 +698,8 @@ BfMethodInstance* BfMethodParam::GetDelegateParamInvoke()
|
|||
auto methodRefType = (BfMethodRefType*)mResolvedType;
|
||||
return methodRefType->mMethodRef;
|
||||
}
|
||||
|
||||
else if (mResolvedType->IsTuple())
|
||||
return NULL;
|
||||
BF_ASSERT(mResolvedType->IsDelegate() || mResolvedType->IsFunction());
|
||||
auto bfModule = BfModule::GetModuleFor(mResolvedType);
|
||||
BfMethodInstance* invokeMethodInstance = bfModule->GetRawMethodInstanceAtIdx(mResolvedType->ToTypeInstance(), 0, "Invoke");
|
||||
|
@ -1166,6 +1167,23 @@ void BfMethodInstance::GetParamName(int paramIdx, StringImpl& name, int& namePre
|
|||
BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
|
||||
if (methodParam->mDelegateParamIdx != -1)
|
||||
{
|
||||
if (methodParam->mResolvedType->IsTuple())
|
||||
{
|
||||
auto tupleType = (BfTupleType*)methodParam->mResolvedType;
|
||||
auto& fieldInstance = tupleType->mFieldInstances[methodParam->mDelegateParamIdx];
|
||||
if (methodParam->mDelegateParamNameCombine)
|
||||
name = paramDef->mName + "__" + fieldInstance.GetFieldDef()->mName;
|
||||
else
|
||||
name = fieldInstance.GetFieldDef()->mName;
|
||||
|
||||
if (name == "p__a__a")
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
|
||||
if (methodParam->mDelegateParamNameCombine)
|
||||
name = paramDef->mName + "__" + invokeMethodInstance->GetParamName(methodParam->mDelegateParamIdx);
|
||||
|
@ -1213,6 +1231,12 @@ BfType* BfMethodInstance::GetParamType(int paramIdx, bool returnUnderlyingParams
|
|||
BfMethodParam* methodParam = &mParams[paramIdx];
|
||||
if (methodParam->mDelegateParamIdx != -1)
|
||||
{
|
||||
if (methodParam->mResolvedType->IsTuple())
|
||||
{
|
||||
auto tupleType = (BfTupleType*)methodParam->mResolvedType;
|
||||
return tupleType->mFieldInstances[methodParam->mDelegateParamIdx].mResolvedType;
|
||||
}
|
||||
|
||||
BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
|
||||
return invokeMethodInstance->GetParamType(methodParam->mDelegateParamIdx, true);
|
||||
}
|
||||
|
@ -1247,6 +1271,8 @@ bool BfMethodInstance::GetParamIsSplat(int paramIdx)
|
|||
if (methodParam->mDelegateParamIdx != -1)
|
||||
{
|
||||
BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
|
||||
if (invokeMethodInstance == NULL)
|
||||
return false;
|
||||
return invokeMethodInstance->GetParamIsSplat(methodParam->mDelegateParamIdx);
|
||||
}
|
||||
return methodParam->mIsSplat;
|
||||
|
|
29
IDEHelper/Tests/src/Params.bf
Normal file
29
IDEHelper/Tests/src/Params.bf
Normal file
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
|
||||
namespace Tests;
|
||||
|
||||
class Params
|
||||
{
|
||||
class ClassA<T> where T : Tuple
|
||||
{
|
||||
public static int Test(delegate int(char8 a, params T) dlg, params T par)
|
||||
{
|
||||
return dlg('A', params par);
|
||||
}
|
||||
}
|
||||
|
||||
class ClassB : ClassA<(int a, float b)>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
int val = ClassB.Test(scope (a, __a, b) =>
|
||||
{
|
||||
return (.)a + (.)__a + (.)b;
|
||||
}, 10, 2.3f);
|
||||
Test.Assert(val == 65+10+2);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue