mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +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)
|
if ((mAllocSizeAndFlags & AttrFlags) == StrPtrFlag)
|
||||||
{
|
{
|
||||||
// It's a reference
|
// It's a reference
|
||||||
char* newPtr = AllocPtr(this->mLength);
|
int allocSize = (int)BF_MAX(GetAllocSize(), this->mLength + 1);
|
||||||
memcpy(newPtr, this->mPtr, this->mLength + 1);
|
char* newPtr = AllocPtr(allocSize);
|
||||||
|
memcpy(newPtr, this->mPtr, this->mLength);
|
||||||
|
newPtr[this->mLength] = 0;
|
||||||
this->mPtr = newPtr;
|
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);
|
public static extern bool Equals<T>(T val1, T val2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Tuple
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
struct Function : int
|
struct Function : int
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -478,6 +478,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mTypeTypeDef = NULL;
|
mTypeTypeDef = NULL;
|
||||||
mUnboundAttributeTypeDef = NULL;
|
mUnboundAttributeTypeDef = NULL;
|
||||||
mValueTypeTypeDef = NULL;
|
mValueTypeTypeDef = NULL;
|
||||||
|
mTupleTypeDef = NULL;
|
||||||
mResultTypeDef = NULL;
|
mResultTypeDef = NULL;
|
||||||
mObsoleteAttributeTypeDef = NULL;
|
mObsoleteAttributeTypeDef = NULL;
|
||||||
mErrorAttributeTypeDef = NULL;
|
mErrorAttributeTypeDef = NULL;
|
||||||
|
@ -7334,6 +7335,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mTypeTypeDef = _GetRequiredType("System.Type");
|
mTypeTypeDef = _GetRequiredType("System.Type");
|
||||||
mUnboundAttributeTypeDef = _GetRequiredType("System.UnboundAttribute");
|
mUnboundAttributeTypeDef = _GetRequiredType("System.UnboundAttribute");
|
||||||
mValueTypeTypeDef = _GetRequiredType("System.ValueType");
|
mValueTypeTypeDef = _GetRequiredType("System.ValueType");
|
||||||
|
mTupleTypeDef = _GetRequiredType("System.Tuple");
|
||||||
mObsoleteAttributeTypeDef = _GetRequiredType("System.ObsoleteAttribute");
|
mObsoleteAttributeTypeDef = _GetRequiredType("System.ObsoleteAttribute");
|
||||||
mErrorAttributeTypeDef = _GetRequiredType("System.ErrorAttribute");
|
mErrorAttributeTypeDef = _GetRequiredType("System.ErrorAttribute");
|
||||||
mWarnAttributeTypeDef = _GetRequiredType("System.WarnAttribute");
|
mWarnAttributeTypeDef = _GetRequiredType("System.WarnAttribute");
|
||||||
|
|
|
@ -379,6 +379,7 @@ public:
|
||||||
BfTypeDef* mTypeTypeDeclDef;
|
BfTypeDef* mTypeTypeDeclDef;
|
||||||
BfTypeDef* mTypeTypeDef;
|
BfTypeDef* mTypeTypeDef;
|
||||||
BfTypeDef* mValueTypeTypeDef;
|
BfTypeDef* mValueTypeTypeDef;
|
||||||
|
BfTypeDef* mTupleTypeDef;
|
||||||
BfTypeDef* mResultTypeDef;
|
BfTypeDef* mResultTypeDef;
|
||||||
BfTypeDef* mGCTypeDef;
|
BfTypeDef* mGCTypeDef;
|
||||||
BfTypeDef* mGenericIEnumerableTypeDef;
|
BfTypeDef* mGenericIEnumerableTypeDef;
|
||||||
|
|
|
@ -14741,30 +14741,19 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
||||||
|
|
||||||
if (invokeMethodInstance != NULL)
|
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())
|
if (paramIdx < (int)lambdaBindExpr->mParams.size())
|
||||||
{
|
{
|
||||||
localVar->mName = lambdaBindExpr->mParams[paramIdx]->ToString();
|
localVar->mName = lambdaBindExpr->mParams[paramIdx]->ToString();
|
||||||
localVar->mNameNode = lambdaBindExpr->mParams[paramIdx];
|
localVar->mNameNode = lambdaBindExpr->mParams[paramIdx];
|
||||||
paramDef->mParamDeclaration->mNameNode = lambdaBindExpr->mParams[paramIdx];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mModule->AssertErrorState();
|
mModule->AssertErrorState();
|
||||||
localVar->mName = invokeParamDef->mName;
|
localVar->mName = invokeMethodInstance->GetParamName(paramIdx);
|
||||||
paramDef->mParamDeclaration->mNameNode = NULL;
|
|
||||||
}
|
}
|
||||||
paramDef->mName = localVar->mName;
|
|
||||||
methodDef->mParams.push_back(paramDef);
|
|
||||||
|
|
||||||
localVar->mResolvedType = invokeMethodInstance->GetParamType(paramIdx);
|
localVar->mResolvedType = invokeMethodInstance->GetParamType(paramIdx);
|
||||||
mModule->PopulateType(localVar->mResolvedType);
|
mModule->PopulateType(localVar->mResolvedType);
|
||||||
localVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
|
localVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
|
||||||
|
@ -14775,13 +14764,39 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
||||||
|
|
||||||
mModule->DoAddLocalVariable(localVar);
|
mModule->DoAddLocalVariable(localVar);
|
||||||
|
|
||||||
if (autoComplete != NULL)
|
|
||||||
autoComplete->CheckLocalDef(BfNodeDynCast<BfIdentifierNode>(paramDef->mParamDeclaration->mNameNode), methodState.mLocals.back());
|
|
||||||
auto resolvePassData = mModule->mCompiler->mResolvePassData;
|
auto resolvePassData = mModule->mCompiler->mResolvePassData;
|
||||||
if (resolvePassData != NULL)
|
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);
|
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();
|
bool isAutocomplete = mModule->mCompiler->IsAutocomplete();
|
||||||
|
@ -24091,12 +24106,17 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
|
||||||
rightTypedValueExpr.mRefNode = opToken;
|
rightTypedValueExpr.mRefNode = opToken;
|
||||||
|
|
||||||
auto valueTypeEmpty = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mBaseType->mBaseType), {});
|
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;
|
SizedArray<BfIRValue, 8> enumMembers;
|
||||||
enumMembers.Add(valueTypeEmpty);
|
enumMembers.Add(valueTypeEmpty);
|
||||||
auto enumValue = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mBaseType), enumMembers);
|
auto enumValue = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mBaseType), enumMembers);
|
||||||
|
|
||||||
SizedArray<BfIRValue, 8> tupleMembers;
|
SizedArray<BfIRValue, 8> tupleMembers;
|
||||||
tupleMembers.Add(valueTypeEmpty);
|
tupleMembers.Add(tupleTypeEmpty);
|
||||||
tupleMembers.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1));
|
tupleMembers.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1));
|
||||||
auto tupleValue = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mFieldInstances[0].mResolvedType), tupleMembers);
|
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");
|
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)
|
if (failHandleKind == BfFailHandleKind_Normal)
|
||||||
{
|
|
||||||
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);
|
FatalError(error);
|
||||||
|
else if (failHandleKind == BfFailHandleKind_Soft)
|
||||||
|
InternalError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::InternalError(const StringImpl& error, BfAstNode* refNode, const char* file, int line)
|
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;
|
String fullError = error;
|
||||||
|
|
||||||
if (file != NULL)
|
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);
|
fullError += StrFormat("\nSource Location: %s:%d", mCurFilePosition.mFileInstance->mParser->mFileName.c_str(), mCurFilePosition.mCurLine + 1);
|
||||||
|
|
||||||
Fail(String("INTERNAL ERROR: ") + fullError, refNode);
|
Fail(String("INTERNAL ERROR: ") + fullError, refNode);
|
||||||
|
|
||||||
|
isInside = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::NotImpl(BfAstNode* astNode)
|
void BfModule::NotImpl(BfAstNode* astNode)
|
||||||
|
@ -16018,6 +16017,8 @@ BfIRValue BfModule::AllocLocalVariable(BfType* type, const StringImpl& name, boo
|
||||||
|
|
||||||
void BfModule::DoAddLocalVariable(BfLocalVariable* localVar)
|
void BfModule::DoAddLocalVariable(BfLocalVariable* localVar)
|
||||||
{
|
{
|
||||||
|
BF_ASSERT(localVar->mResolvedType != NULL);
|
||||||
|
|
||||||
while (localVar->mName.StartsWith('@'))
|
while (localVar->mName.StartsWith('@'))
|
||||||
{
|
{
|
||||||
localVar->mNamePrefixCount++;
|
localVar->mNamePrefixCount++;
|
||||||
|
@ -17064,7 +17065,7 @@ void BfModule::AssertErrorState()
|
||||||
if (mCompiler->mPassInstance->HasFailed())
|
if (mCompiler->mPassInstance->HasFailed())
|
||||||
return;
|
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()
|
void BfModule::AssertParseErrorState()
|
||||||
|
@ -20008,14 +20009,17 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
||||||
{
|
{
|
||||||
if (compositeVariableIdx == -1)
|
if (compositeVariableIdx == -1)
|
||||||
{
|
{
|
||||||
compositeVariableIdx = (int)mCurMethodState->mLocals.size();
|
|
||||||
|
|
||||||
BfLocalVariable* localVar = new BfLocalVariable();
|
|
||||||
auto paramInst = &methodInstance->mParams[paramIdx];
|
auto paramInst = &methodInstance->mParams[paramIdx];
|
||||||
auto paramDef = methodDef->mParams[paramInst->mParamDefIdx];
|
auto paramDef = methodDef->mParams[paramInst->mParamDefIdx];
|
||||||
|
|
||||||
|
compositeVariableIdx = (int)mCurMethodState->mLocals.size();
|
||||||
|
BfLocalVariable* localVar = new BfLocalVariable();
|
||||||
localVar->mName = paramDef->mName;
|
localVar->mName = paramDef->mName;
|
||||||
localVar->mNamePrefixCount = paramDef->mNamePrefixCount;
|
localVar->mNamePrefixCount = paramDef->mNamePrefixCount;
|
||||||
|
if (paramDef->mTypeRef != NULL)
|
||||||
localVar->mResolvedType = ResolveTypeRef(paramDef->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_NoResolveGenericParam);
|
localVar->mResolvedType = ResolveTypeRef(paramDef->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_NoResolveGenericParam);
|
||||||
|
if (localVar->mResolvedType == NULL)
|
||||||
|
localVar->mResolvedType = GetPrimitiveType(BfTypeCode_None);
|
||||||
localVar->mCompositeCount = 0;
|
localVar->mCompositeCount = 0;
|
||||||
DoAddLocalVariable(localVar);
|
DoAddLocalVariable(localVar);
|
||||||
}
|
}
|
||||||
|
@ -20064,9 +20068,9 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
||||||
if (genericParamInstance->mTypeConstraint != NULL)
|
if (genericParamInstance->mTypeConstraint != NULL)
|
||||||
{
|
{
|
||||||
auto typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance();
|
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 != 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();
|
BfLocalVariable* localVar = new BfLocalVariable();
|
||||||
localVar->mName = paramDef->mName;
|
localVar->mName = paramDef->mName;
|
||||||
|
@ -24965,10 +24969,43 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
isValid = true;
|
isValid = true;
|
||||||
addParams = false;
|
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())
|
else if (resolvedParamType->IsGenericParam())
|
||||||
{
|
{
|
||||||
auto genericParamInstance = GetGenericParamInstance((BfGenericParamType*)resolvedParamType);
|
auto genericParamInstance = GetGenericParamInstance((BfGenericParamType*)resolvedParamType, false, BfFailHandleKind_Ignore);
|
||||||
if (genericParamInstance->mTypeConstraint != NULL)
|
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();
|
auto typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance();
|
||||||
if ((genericParamInstance->mTypeConstraint->IsArray()) || (genericParamInstance->mTypeConstraint->IsSizedArray()))
|
if ((genericParamInstance->mTypeConstraint->IsArray()) || (genericParamInstance->mTypeConstraint->IsSizedArray()))
|
||||||
|
@ -24979,9 +25016,9 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
mCurMethodInstance->mParams.Add(methodParam);
|
mCurMethodInstance->mParams.Add(methodParam);
|
||||||
isValid = true;
|
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) &&
|
((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;
|
mCurMethodInstance->mHadGenericDelegateParams = true;
|
||||||
isValid = true;
|
isValid = true;
|
||||||
|
@ -25055,13 +25092,25 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
{
|
{
|
||||||
if (usedParamDefIdx[methodParam.mParamDefIdx] > 1)
|
if (usedParamDefIdx[methodParam.mParamDefIdx] > 1)
|
||||||
methodParam.mDelegateParamNameCombine = true;
|
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();
|
BfMethodInstance* invokeMethodInstance = methodParam.GetDelegateParamInvoke();
|
||||||
String paramName = invokeMethodInstance->GetParamName(methodParam.mDelegateParamIdx);
|
String paramName = invokeMethodInstance->GetParamName(methodParam.mDelegateParamIdx);
|
||||||
if (usedNames.Contains(paramName))
|
if (!usedNames.Add(paramName))
|
||||||
methodParam.mDelegateParamNameCombine = true;
|
methodParam.mDelegateParamNameCombine = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int argIdx = 0;
|
int argIdx = 0;
|
||||||
resolveModule->PopulateType(methodInstance->mReturnType, BfPopulateType_Data);
|
resolveModule->PopulateType(methodInstance->mReturnType, BfPopulateType_Data);
|
||||||
|
|
|
@ -1617,6 +1617,7 @@ public:
|
||||||
public:
|
public:
|
||||||
void FatalError(const StringImpl& error, const char* file = NULL, int line = -1, int column = -1);
|
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, 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 InternalError(const StringImpl& error, BfAstNode* refNode = NULL, const char* file = NULL, int line = -1);
|
||||||
void NotImpl(BfAstNode* astNode);
|
void NotImpl(BfAstNode* astNode);
|
||||||
void AddMethodReference(const BfMethodRef& methodRef, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
|
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* ResolveGenericType(BfType* unspecializedType, BfTypeVector* typeGenericArguments, BfTypeVector* methodGenericArguments, BfType* selfType, bool allowFail = false);
|
||||||
BfType* ResolveSelfType(BfType* type, BfType* selfType);
|
BfType* ResolveSelfType(BfType* type, BfType* selfType);
|
||||||
bool IsUnboundGeneric(BfType* type);
|
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);
|
BfGenericParamInstance* GetGenericParamInstance(BfGenericParamType* type, bool checkMixinBind = false, BfFailHandleKind failHandleKind = BfFailHandleKind_Normal);
|
||||||
void GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInstance*, 4>& genericParamInstance);
|
void GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInstance*, 4>& genericParamInstance);
|
||||||
BfGenericParamInstance* GetMergedGenericParamData(BfType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint);
|
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);
|
baseType = ResolveTypeDef(mCompiler->mPointerTTypeDef, BfPopulateType_Data);
|
||||||
}
|
}
|
||||||
|
else if (resolvedTypeRef->IsTuple())
|
||||||
|
{
|
||||||
|
baseType = ResolveTypeDef(mCompiler->mTupleTypeDef, BfPopulateType_Data);
|
||||||
|
}
|
||||||
else if ((resolvedTypeRef->IsValueType()) && (typeDef != mCompiler->mValueTypeTypeDef))
|
else if ((resolvedTypeRef->IsValueType()) && (typeDef != mCompiler->mValueTypeTypeDef))
|
||||||
{
|
{
|
||||||
baseType = ResolveTypeDef(mCompiler->mValueTypeTypeDef, BfPopulateType_Data)->ToTypeInstance();
|
baseType = ResolveTypeDef(mCompiler->mValueTypeTypeDef, BfPopulateType_Data)->ToTypeInstance();
|
||||||
|
@ -9565,7 +9569,7 @@ bool BfModule::IsUnboundGeneric(BfType* type)
|
||||||
return (genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0;
|
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
|
// When we're evaluating a method, make sure the params refer back to that method context
|
||||||
auto curTypeInstance = mCurTypeInstance;
|
auto curTypeInstance = mCurTypeInstance;
|
||||||
|
@ -9577,7 +9581,7 @@ BfGenericParamInstance* BfModule::GetGenericTypeParamInstance(int genericParamId
|
||||||
|
|
||||||
if (genericTypeInst == NULL)
|
if (genericTypeInst == NULL)
|
||||||
{
|
{
|
||||||
FatalError("Invalid mCurTypeInstance for GetGenericTypeParamInstance");
|
FatalError("Invalid mCurTypeInstance for GetGenericTypeParamInstance", failHandleKind);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9756,7 +9760,7 @@ BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* ty
|
||||||
return curGenericMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx];
|
return curGenericMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetGenericTypeParamInstance(type->mGenericParamIdx);
|
return GetGenericTypeParamInstance(type->mGenericParamIdx, failHandleKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfModule::ResolveTypeResult_Validate(BfAstNode* typeRef, BfType* resolvedTypeRef)
|
bool BfModule::ResolveTypeResult_Validate(BfAstNode* typeRef, BfType* resolvedTypeRef)
|
||||||
|
|
|
@ -698,7 +698,8 @@ BfMethodInstance* BfMethodParam::GetDelegateParamInvoke()
|
||||||
auto methodRefType = (BfMethodRefType*)mResolvedType;
|
auto methodRefType = (BfMethodRefType*)mResolvedType;
|
||||||
return methodRefType->mMethodRef;
|
return methodRefType->mMethodRef;
|
||||||
}
|
}
|
||||||
|
else if (mResolvedType->IsTuple())
|
||||||
|
return NULL;
|
||||||
BF_ASSERT(mResolvedType->IsDelegate() || mResolvedType->IsFunction());
|
BF_ASSERT(mResolvedType->IsDelegate() || mResolvedType->IsFunction());
|
||||||
auto bfModule = BfModule::GetModuleFor(mResolvedType);
|
auto bfModule = BfModule::GetModuleFor(mResolvedType);
|
||||||
BfMethodInstance* invokeMethodInstance = bfModule->GetRawMethodInstanceAtIdx(mResolvedType->ToTypeInstance(), 0, "Invoke");
|
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];
|
BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
|
||||||
if (methodParam->mDelegateParamIdx != -1)
|
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();
|
BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
|
||||||
if (methodParam->mDelegateParamNameCombine)
|
if (methodParam->mDelegateParamNameCombine)
|
||||||
name = paramDef->mName + "__" + invokeMethodInstance->GetParamName(methodParam->mDelegateParamIdx);
|
name = paramDef->mName + "__" + invokeMethodInstance->GetParamName(methodParam->mDelegateParamIdx);
|
||||||
|
@ -1213,6 +1231,12 @@ BfType* BfMethodInstance::GetParamType(int paramIdx, bool returnUnderlyingParams
|
||||||
BfMethodParam* methodParam = &mParams[paramIdx];
|
BfMethodParam* methodParam = &mParams[paramIdx];
|
||||||
if (methodParam->mDelegateParamIdx != -1)
|
if (methodParam->mDelegateParamIdx != -1)
|
||||||
{
|
{
|
||||||
|
if (methodParam->mResolvedType->IsTuple())
|
||||||
|
{
|
||||||
|
auto tupleType = (BfTupleType*)methodParam->mResolvedType;
|
||||||
|
return tupleType->mFieldInstances[methodParam->mDelegateParamIdx].mResolvedType;
|
||||||
|
}
|
||||||
|
|
||||||
BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
|
BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
|
||||||
return invokeMethodInstance->GetParamType(methodParam->mDelegateParamIdx, true);
|
return invokeMethodInstance->GetParamType(methodParam->mDelegateParamIdx, true);
|
||||||
}
|
}
|
||||||
|
@ -1247,6 +1271,8 @@ bool BfMethodInstance::GetParamIsSplat(int paramIdx)
|
||||||
if (methodParam->mDelegateParamIdx != -1)
|
if (methodParam->mDelegateParamIdx != -1)
|
||||||
{
|
{
|
||||||
BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
|
BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
|
||||||
|
if (invokeMethodInstance == NULL)
|
||||||
|
return false;
|
||||||
return invokeMethodInstance->GetParamIsSplat(methodParam->mDelegateParamIdx);
|
return invokeMethodInstance->GetParamIsSplat(methodParam->mDelegateParamIdx);
|
||||||
}
|
}
|
||||||
return methodParam->mIsSplat;
|
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