mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Partial explicit generic method arguments with ... or ?
This commit is contained in:
parent
662566ed16
commit
f4f10fce99
8 changed files with 155 additions and 66 deletions
|
@ -137,7 +137,7 @@ BfBaseClassWalker::Entry BfBaseClassWalker::Next()
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
BfMethodMatcher::BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, const StringImpl& methodName, SizedArrayImpl<BfResolvedArg>& arguments, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments) :
|
BfMethodMatcher::BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, const StringImpl& methodName, SizedArrayImpl<BfResolvedArg>& arguments, const BfMethodGenericArguments& methodGenericArguments) :
|
||||||
mArguments(arguments)
|
mArguments(arguments)
|
||||||
{
|
{
|
||||||
mTargetSrc = targetSrc;
|
mTargetSrc = targetSrc;
|
||||||
|
@ -146,7 +146,7 @@ BfMethodMatcher::BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, const S
|
||||||
Init(/*arguments, */methodGenericArguments);
|
Init(/*arguments, */methodGenericArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
BfMethodMatcher::BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* interfaceMethodInstance, SizedArrayImpl<BfResolvedArg>& arguments, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments) :
|
BfMethodMatcher::BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* interfaceMethodInstance, SizedArrayImpl<BfResolvedArg>& arguments, const BfMethodGenericArguments& methodGenericArguments) :
|
||||||
mArguments(arguments)
|
mArguments(arguments)
|
||||||
{
|
{
|
||||||
mTargetSrc = targetSrc;
|
mTargetSrc = targetSrc;
|
||||||
|
@ -156,7 +156,7 @@ BfMethodMatcher::BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, BfMetho
|
||||||
mMethodName = mInterfaceMethodInstance->mMethodDef->mName;
|
mMethodName = mInterfaceMethodInstance->mMethodDef->mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfMethodMatcher::Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments)
|
void BfMethodMatcher::Init(const BfMethodGenericArguments& methodGenericArguments)
|
||||||
{
|
{
|
||||||
//mArguments = arguments;
|
//mArguments = arguments;
|
||||||
mActiveTypeDef = NULL;
|
mActiveTypeDef = NULL;
|
||||||
|
@ -170,6 +170,8 @@ void BfMethodMatcher::Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSized
|
||||||
mMethodType = BfMethodType_Normal;
|
mMethodType = BfMethodType_Normal;
|
||||||
mCheckReturnType = NULL;
|
mCheckReturnType = NULL;
|
||||||
mHadExplicitGenericArguments = false;
|
mHadExplicitGenericArguments = false;
|
||||||
|
mHadOpenGenericArguments = methodGenericArguments.mIsOpen;
|
||||||
|
mHadPartialGenericArguments = methodGenericArguments.mIsPartial;
|
||||||
mHasVarArguments = false;
|
mHasVarArguments = false;
|
||||||
mInterfaceMethodInstance = NULL;
|
mInterfaceMethodInstance = NULL;
|
||||||
mFakeConcreteTarget = false;
|
mFakeConcreteTarget = false;
|
||||||
|
@ -202,16 +204,25 @@ void BfMethodMatcher::Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSized
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (methodGenericArguments != NULL)
|
if (methodGenericArguments.mArguments != NULL)
|
||||||
{
|
{
|
||||||
for (BfAstNode* genericArg : *methodGenericArguments)
|
for (BfAstNode* genericArg : *(methodGenericArguments.mArguments))
|
||||||
{
|
{
|
||||||
auto genericArgType = mModule->ResolveTypeRef(genericArg, NULL, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowImplicitConstExpr);
|
BfType* genericArgType = NULL;
|
||||||
if ((genericArgType != NULL) && (genericArgType->IsGenericParam()))
|
if (BfNodeIsA<BfUninitializedExpression>(genericArg))
|
||||||
{
|
{
|
||||||
auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)genericArgType);
|
// Allow a null here
|
||||||
if ((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
|
BF_ASSERT(mHadPartialGenericArguments);
|
||||||
mHasVarArguments = true;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
genericArgType = mModule->ResolveTypeRef(genericArg, NULL, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowImplicitConstExpr);
|
||||||
|
if ((genericArgType != NULL) && (genericArgType->IsGenericParam()))
|
||||||
|
{
|
||||||
|
auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)genericArgType);
|
||||||
|
if ((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
|
||||||
|
mHasVarArguments = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mExplicitMethodGenericArguments.push_back(genericArgType);
|
mExplicitMethodGenericArguments.push_back(genericArgType);
|
||||||
}
|
}
|
||||||
|
@ -1705,7 +1716,8 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
int argIdx = 0;
|
int argIdx = 0;
|
||||||
int argMatchCount = 0;
|
int argMatchCount = 0;
|
||||||
|
|
||||||
bool needInferGenericParams = (checkMethod->mGenericParams.size() != 0) && (!mHadExplicitGenericArguments);
|
bool needInferGenericParams = (checkMethod->mGenericParams.size() != 0) &&
|
||||||
|
((!mHadExplicitGenericArguments) || (mHadPartialGenericArguments));
|
||||||
int paramIdx = 0;
|
int paramIdx = 0;
|
||||||
BfType* paramsElementType = NULL;
|
BfType* paramsElementType = NULL;
|
||||||
if (checkMethod->mHasAppend)
|
if (checkMethod->mHasAppend)
|
||||||
|
@ -1713,8 +1725,20 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
|
|
||||||
int uniqueGenericStartIdx = mModule->GetLocalInferrableGenericArgCount(checkMethod);
|
int uniqueGenericStartIdx = mModule->GetLocalInferrableGenericArgCount(checkMethod);
|
||||||
|
|
||||||
if ((mHadExplicitGenericArguments) && (checkMethod->mGenericParams.size() != mExplicitMethodGenericArguments.size() + uniqueGenericStartIdx))
|
if (mHadExplicitGenericArguments)
|
||||||
goto NoMatch;
|
{
|
||||||
|
int genericArgDelta = (int)(checkMethod->mGenericParams.size() - (mExplicitMethodGenericArguments.size() + uniqueGenericStartIdx));
|
||||||
|
if (mHadOpenGenericArguments)
|
||||||
|
{
|
||||||
|
if (genericArgDelta <= 0)
|
||||||
|
goto NoMatch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (genericArgDelta != 0)
|
||||||
|
goto NoMatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& checkGenericArgRef : mCheckMethodGenericArguments)
|
for (auto& checkGenericArgRef : mCheckMethodGenericArguments)
|
||||||
checkGenericArgRef = NULL;
|
checkGenericArgRef = NULL;
|
||||||
|
@ -1741,6 +1765,13 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
{
|
{
|
||||||
genericArgumentsSubstitute = &mExplicitMethodGenericArguments;
|
genericArgumentsSubstitute = &mExplicitMethodGenericArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((mHadPartialGenericArguments) && (needInferGenericParams))
|
||||||
|
{
|
||||||
|
genericArgumentsSubstitute = &mCheckMethodGenericArguments;
|
||||||
|
for (int i = 0; i < (int)mExplicitMethodGenericArguments.mSize; i++)
|
||||||
|
mCheckMethodGenericArguments[i] = mExplicitMethodGenericArguments[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (needInferGenericParams)
|
else if (needInferGenericParams)
|
||||||
genericArgumentsSubstitute = &mCheckMethodGenericArguments;
|
genericArgumentsSubstitute = &mCheckMethodGenericArguments;
|
||||||
|
@ -3780,7 +3811,7 @@ void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolation
|
||||||
BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
|
BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
|
||||||
BfResolvedArgs argValues(&sizedArgExprs);
|
BfResolvedArgs argValues(&sizedArgExprs);
|
||||||
ResolveArgValues(argValues, BfResolveArgsFlag_InsideStringInterpolationAlloc);
|
ResolveArgValues(argValues, BfResolveArgsFlag_InsideStringInterpolationAlloc);
|
||||||
MatchMethod(stringInterpolationExpression, NULL, newString, false, false, "AppendF", argValues, NULL);
|
MatchMethod(stringInterpolationExpression, NULL, newString, false, false, "AppendF", argValues, BfMethodGenericArguments());
|
||||||
mResult = newString;
|
mResult = newString;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -7666,7 +7697,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
||||||
static int sCtorCount = 0;
|
static int sCtorCount = 0;
|
||||||
sCtorCount++;
|
sCtorCount++;
|
||||||
|
|
||||||
BfMethodMatcher methodMatcher(targetSrc, mModule, "", argValues.mResolvedArgs, NULL);
|
BfMethodMatcher methodMatcher(targetSrc, mModule, "", argValues.mResolvedArgs, BfMethodGenericArguments());
|
||||||
methodMatcher.mBfEvalExprFlags = mBfEvalExprFlags;
|
methodMatcher.mBfEvalExprFlags = mBfEvalExprFlags;
|
||||||
|
|
||||||
BfTypeVector typeGenericArguments;
|
BfTypeVector typeGenericArguments;
|
||||||
|
@ -8251,10 +8282,12 @@ bool BfExprEvaluator::CheckGenericCtor(BfGenericParamType* genericParamType, BfR
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& methodName,
|
BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& methodName,
|
||||||
BfResolvedArgs& argValues, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments, BfCheckedKind checkedKind)
|
BfResolvedArgs& argValues, const BfMethodGenericArguments& methodGenericArgs, BfCheckedKind checkedKind)
|
||||||
{
|
{
|
||||||
BP_ZONE("MatchMethod");
|
BP_ZONE("MatchMethod");
|
||||||
|
|
||||||
|
auto methodGenericArguments = methodGenericArgs.mArguments;
|
||||||
|
|
||||||
if (bypassVirtual)
|
if (bypassVirtual)
|
||||||
{
|
{
|
||||||
// "bypassVirtual" means that we know for sure that the target is EXACTLY the specified target type,
|
// "bypassVirtual" means that we know for sure that the target is EXACTLY the specified target type,
|
||||||
|
@ -8534,7 +8567,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
|
|
||||||
BfTypeInstance* curTypeInst = targetTypeInst;
|
BfTypeInstance* curTypeInst = targetTypeInst;
|
||||||
|
|
||||||
BfMethodMatcher methodMatcher(targetSrc, mModule, methodName, argValues.mResolvedArgs, methodGenericArguments);
|
BfMethodMatcher methodMatcher(targetSrc, mModule, methodName, argValues.mResolvedArgs, methodGenericArgs);
|
||||||
methodMatcher.mOrigTarget = origTarget;
|
methodMatcher.mOrigTarget = origTarget;
|
||||||
methodMatcher.mTarget = target;
|
methodMatcher.mTarget = target;
|
||||||
methodMatcher.mCheckedKind = checkedKind;
|
methodMatcher.mCheckedKind = checkedKind;
|
||||||
|
@ -9053,7 +9086,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
{
|
{
|
||||||
mFunctionBindResult->mOrigTarget = BfTypedValue();
|
mFunctionBindResult->mOrigTarget = BfTypedValue();
|
||||||
}
|
}
|
||||||
return MatchMethod(targetSrc, NULL, fieldVal, false, false, "Invoke", argValues, methodGenericArguments, checkedKind);
|
return MatchMethod(targetSrc, NULL, fieldVal, false, false, "Invoke", argValues, methodGenericArgs, checkedKind);
|
||||||
}
|
}
|
||||||
if (IsVar(fieldVal.mType))
|
if (IsVar(fieldVal.mType))
|
||||||
{
|
{
|
||||||
|
@ -9634,7 +9667,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
autoComplete->mIsGetDefinition = false;
|
autoComplete->mIsGetDefinition = false;
|
||||||
result = mModule->MakeAddressable(result);
|
result = mModule->MakeAddressable(result);
|
||||||
BfResolvedArgs resolvedArgs;
|
BfResolvedArgs resolvedArgs;
|
||||||
MatchMethod(targetSrc, NULL, result, false, false, "ReturnValueDiscarded", resolvedArgs, NULL);
|
MatchMethod(targetSrc, NULL, result, false, false, "ReturnValueDiscarded", resolvedArgs, BfMethodGenericArguments());
|
||||||
if (wasGetDefinition)
|
if (wasGetDefinition)
|
||||||
autoComplete->mIsGetDefinition = true;
|
autoComplete->mIsGetDefinition = true;
|
||||||
}
|
}
|
||||||
|
@ -10534,7 +10567,7 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
|
||||||
BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
|
BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
|
||||||
BfResolvedArgs argValues(&sizedArgExprs);
|
BfResolvedArgs argValues(&sizedArgExprs);
|
||||||
exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
||||||
exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, NULL);
|
exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, BfMethodGenericArguments());
|
||||||
|
|
||||||
if (addFunctionBindResult.mMethodInstance != NULL)
|
if (addFunctionBindResult.mMethodInstance != NULL)
|
||||||
CreateCall(initExpr, addFunctionBindResult.mMethodInstance, addFunctionBindResult.mFunc, true, addFunctionBindResult.mIRArgs);
|
CreateCall(initExpr, addFunctionBindResult.mMethodInstance, addFunctionBindResult.mFunc, true, addFunctionBindResult.mIRArgs);
|
||||||
|
@ -11598,16 +11631,16 @@ bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr
|
||||||
args[i] = typedValueExpr;
|
args[i] = typedValueExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments = NULL;
|
BfMethodGenericArguments methodGenericArgs;
|
||||||
if (delegateBindExpr->mGenericArgs != NULL)
|
if (delegateBindExpr->mGenericArgs != NULL)
|
||||||
methodGenericArguments = &delegateBindExpr->mGenericArgs->mGenericArgs;
|
methodGenericArgs.mArguments = &delegateBindExpr->mGenericArgs->mGenericArgs;
|
||||||
|
|
||||||
BfFunctionBindResult bindResult;
|
BfFunctionBindResult bindResult;
|
||||||
bindResult.mSkipMutCheck = true; // Allow operating on copies
|
bindResult.mSkipMutCheck = true; // Allow operating on copies
|
||||||
bindResult.mBindType = expectingType;
|
bindResult.mBindType = expectingType;
|
||||||
mFunctionBindResult = &bindResult;
|
mFunctionBindResult = &bindResult;
|
||||||
SetAndRestoreValue<bool> ignoreError(mModule->mIgnoreErrors, true);
|
SetAndRestoreValue<bool> ignoreError(mModule->mIgnoreErrors, true);
|
||||||
DoInvocation(delegateBindExpr->mTarget, delegateBindExpr, args, methodGenericArguments);
|
DoInvocation(delegateBindExpr->mTarget, delegateBindExpr, args, methodGenericArgs);
|
||||||
mFunctionBindResult = NULL;
|
mFunctionBindResult = NULL;
|
||||||
if (bindResult.mMethodInstance == NULL)
|
if (bindResult.mMethodInstance == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
@ -12002,9 +12035,9 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
||||||
args[i] = typedValueExpr;
|
args[i] = typedValueExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments = NULL;
|
BfMethodGenericArguments methodGenericArgs;
|
||||||
if (delegateBindExpr->mGenericArgs != NULL)
|
if (delegateBindExpr->mGenericArgs != NULL)
|
||||||
methodGenericArguments = &delegateBindExpr->mGenericArgs->mGenericArgs;
|
methodGenericArgs.mArguments = &delegateBindExpr->mGenericArgs->mGenericArgs;
|
||||||
|
|
||||||
if (delegateBindExpr->mTarget == NULL)
|
if (delegateBindExpr->mTarget == NULL)
|
||||||
{
|
{
|
||||||
|
@ -12034,7 +12067,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<BfType*> prevExpectingType(mExpectingType, methodInstance->mReturnType);
|
SetAndRestoreValue<BfType*> prevExpectingType(mExpectingType, methodInstance->mReturnType);
|
||||||
mFunctionBindResult = &bindResult;
|
mFunctionBindResult = &bindResult;
|
||||||
DoInvocation(delegateBindExpr->mTarget, delegateBindExpr, args, methodGenericArguments);
|
DoInvocation(delegateBindExpr->mTarget, delegateBindExpr, args, methodGenericArgs);
|
||||||
mFunctionBindResult = NULL;
|
mFunctionBindResult = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15289,7 +15322,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
}
|
}
|
||||||
mModule->Fail(StrFormat("Too many generic arguments, expected %d fewer", genericArgCountDiff), errorNode);
|
mModule->Fail(StrFormat("Too many generic arguments, expected %d fewer", genericArgCountDiff), errorNode);
|
||||||
}
|
}
|
||||||
else if (genericArgCountDiff < 0)
|
else if ((genericArgCountDiff < 0) && (!methodMatcher.mHadOpenGenericArguments))
|
||||||
{
|
{
|
||||||
BfAstNode* errorNode = targetSrc;
|
BfAstNode* errorNode = targetSrc;
|
||||||
if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL) && (invocationExpr->mGenericArgs->mCloseChevron != NULL))
|
if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL) && (invocationExpr->mGenericArgs->mCloseChevron != NULL))
|
||||||
|
@ -15646,7 +15679,7 @@ void BfExprEvaluator::CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, bool allowImplicitThis, const StringImpl& name, const BfSizedArray<BfExpression*>& arguments, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArgs)
|
void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, bool allowImplicitThis, const StringImpl& name, const BfSizedArray<BfExpression*>& arguments, const BfMethodGenericArguments& methodGenericArgs)
|
||||||
{
|
{
|
||||||
if (mModule->mCurMethodState == NULL)
|
if (mModule->mCurMethodState == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -16512,8 +16545,10 @@ void BfExprEvaluator::SetMethodElementType(BfAstNode* target)
|
||||||
mModule->SetElementType(target, BfSourceElementType_Method);
|
mModule->SetElementType(target, BfSourceElementType_Method);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray<BfExpression*>& args, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments, BfTypedValue* outCascadeValue)
|
void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray<BfExpression*>& args, const BfMethodGenericArguments& methodGenericArgs, BfTypedValue* outCascadeValue)
|
||||||
{
|
{
|
||||||
|
auto methodGenericArguments = methodGenericArgs.mArguments;
|
||||||
|
|
||||||
// Just a check
|
// Just a check
|
||||||
mModule->mBfIRBuilder->GetInsertBlock();
|
mModule->mBfIRBuilder->GetInsertBlock();
|
||||||
|
|
||||||
|
@ -17066,7 +17101,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
if ((targetFunctionName != "") && (targetFunctionName[targetFunctionName.length() - 1] == '!'))
|
if ((targetFunctionName != "") && (targetFunctionName[targetFunctionName.length() - 1] == '!'))
|
||||||
{
|
{
|
||||||
targetFunctionName = targetFunctionName.Substring(0, targetFunctionName.length() - 1);
|
targetFunctionName = targetFunctionName.Substring(0, targetFunctionName.length() - 1);
|
||||||
InjectMixin(methodNodeSrc, thisValue, allowImplicitThis, targetFunctionName, args, methodGenericArguments);
|
InjectMixin(methodNodeSrc, thisValue, allowImplicitThis, targetFunctionName, args, methodGenericArgs);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -17161,7 +17196,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
if (isCascade)
|
if (isCascade)
|
||||||
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_InCascade);
|
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_InCascade);
|
||||||
ResolveArgValues(argValues, resolveArgsFlags);
|
ResolveArgValues(argValues, resolveArgsFlags);
|
||||||
mResult = MatchMethod(methodNodeSrc, methodBoundExpr, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, argValues, methodGenericArguments, checkedKind);
|
mResult = MatchMethod(methodNodeSrc, methodBoundExpr, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, argValues, methodGenericArgs, checkedKind);
|
||||||
argValues.HandleFixits(mModule);
|
argValues.HandleFixits(mModule);
|
||||||
|
|
||||||
if (mModule->mAttributeState == &attributeState)
|
if (mModule->mAttributeState == &attributeState)
|
||||||
|
@ -17253,15 +17288,25 @@ void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr)
|
||||||
autoComplete->CheckInvocation(invocationExpr, invocationExpr->mOpenParen, invocationExpr->mCloseParen, invocationExpr->mCommas);
|
autoComplete->CheckInvocation(invocationExpr, invocationExpr->mOpenParen, invocationExpr->mCloseParen, invocationExpr->mCommas);
|
||||||
|
|
||||||
mModule->UpdateExprSrcPos(invocationExpr);
|
mModule->UpdateExprSrcPos(invocationExpr);
|
||||||
BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments = NULL;
|
BfMethodGenericArguments methodGenericArgs;
|
||||||
if (invocationExpr->mGenericArgs != NULL)
|
if (invocationExpr->mGenericArgs != NULL)
|
||||||
methodGenericArguments = &invocationExpr->mGenericArgs->mGenericArgs;
|
{
|
||||||
|
methodGenericArgs.mArguments = &invocationExpr->mGenericArgs->mGenericArgs;
|
||||||
|
if ((!invocationExpr->mGenericArgs->mCommas.IsEmpty()) && (invocationExpr->mGenericArgs->mCommas.back()->mToken == BfToken_DotDotDot))
|
||||||
|
{
|
||||||
|
methodGenericArgs.mIsOpen = true;
|
||||||
|
methodGenericArgs.mIsPartial = true;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < (int)methodGenericArgs.mArguments->mSize; i++)
|
||||||
|
if (BfNodeIsA<BfUninitializedExpression>((*methodGenericArgs.mArguments)[i]))
|
||||||
|
methodGenericArgs.mIsPartial = true;
|
||||||
|
}
|
||||||
SizedArray<BfExpression*, 8> copiedArgs;
|
SizedArray<BfExpression*, 8> copiedArgs;
|
||||||
for (BfExpression* arg : invocationExpr->mArguments)
|
for (BfExpression* arg : invocationExpr->mArguments)
|
||||||
copiedArgs.push_back(arg);
|
copiedArgs.push_back(arg);
|
||||||
|
|
||||||
BfTypedValue cascadeValue;
|
BfTypedValue cascadeValue;
|
||||||
DoInvocation(invocationExpr->mTarget, invocationExpr, copiedArgs, methodGenericArguments, &cascadeValue);
|
DoInvocation(invocationExpr->mTarget, invocationExpr, copiedArgs, methodGenericArgs, &cascadeValue);
|
||||||
|
|
||||||
if (autoComplete != NULL)
|
if (autoComplete != NULL)
|
||||||
{
|
{
|
||||||
|
@ -19916,7 +19961,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
|
||||||
if (!val.mTypedValue)
|
if (!val.mTypedValue)
|
||||||
val.mTypedValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
|
val.mTypedValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
|
||||||
|
|
||||||
BfMethodMatcher methodMatcher(indexerExpr->mTarget, mModule, "[]", mIndexerValues, NULL);
|
BfMethodMatcher methodMatcher(indexerExpr->mTarget, mModule, "[]", mIndexerValues, BfMethodGenericArguments());
|
||||||
methodMatcher.mCheckedKind = checkedKind;
|
methodMatcher.mCheckedKind = checkedKind;
|
||||||
//methodMatcher.CheckType(target.mType->ToTypeInstance(), target, false);
|
//methodMatcher.CheckType(target.mType->ToTypeInstance(), target, false);
|
||||||
|
|
||||||
|
@ -20306,7 +20351,7 @@ BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedVal
|
||||||
BfResolvedArg resolvedArg;
|
BfResolvedArg resolvedArg;
|
||||||
resolvedArg.mTypedValue = inValue;
|
resolvedArg.mTypedValue = inValue;
|
||||||
args.push_back(resolvedArg);
|
args.push_back(resolvedArg);
|
||||||
BfMethodMatcher methodMatcher(opToken, mModule, "", args, NULL);
|
BfMethodMatcher methodMatcher(opToken, mModule, "", args, BfMethodGenericArguments());
|
||||||
methodMatcher.mBfEvalExprFlags = BfEvalExprFlags_NoAutoComplete;
|
methodMatcher.mBfEvalExprFlags = BfEvalExprFlags_NoAutoComplete;
|
||||||
methodMatcher.mAllowImplicitRef = true;
|
methodMatcher.mAllowImplicitRef = true;
|
||||||
BfBaseClassWalker baseClassWalker(inValue.mType, NULL, mModule);
|
BfBaseClassWalker baseClassWalker(inValue.mType, NULL, mModule);
|
||||||
|
@ -21947,7 +21992,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
auto checkLeftType = leftValue.mType;
|
auto checkLeftType = leftValue.mType;
|
||||||
auto checkRightType = rightValue.mType;
|
auto checkRightType = rightValue.mType;
|
||||||
|
|
||||||
BfMethodMatcher methodMatcher(opToken, mModule, "", args, NULL);
|
BfMethodMatcher methodMatcher(opToken, mModule, "", args, BfMethodGenericArguments());
|
||||||
methodMatcher.mAllowImplicitRef = true;
|
methodMatcher.mAllowImplicitRef = true;
|
||||||
methodMatcher.mBfEvalExprFlags = BfEvalExprFlags_NoAutoComplete;
|
methodMatcher.mBfEvalExprFlags = BfEvalExprFlags_NoAutoComplete;
|
||||||
BfBaseClassWalker baseClassWalker(checkLeftType, checkRightType, mModule);
|
BfBaseClassWalker baseClassWalker(checkLeftType, checkRightType, mModule);
|
||||||
|
|
|
@ -157,6 +157,20 @@ public:
|
||||||
void InferGenericArguments(BfMethodInstance* methodInstance);
|
void InferGenericArguments(BfMethodInstance* methodInstance);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BfMethodGenericArguments
|
||||||
|
{
|
||||||
|
BfSizedArray<BfAstNode*>* mArguments;
|
||||||
|
bool mIsPartial;
|
||||||
|
bool mIsOpen; // Ends with ...
|
||||||
|
|
||||||
|
BfMethodGenericArguments()
|
||||||
|
{
|
||||||
|
mArguments = NULL;
|
||||||
|
mIsPartial = false;
|
||||||
|
mIsOpen = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class BfMethodMatcher
|
class BfMethodMatcher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -194,6 +208,8 @@ public:
|
||||||
BfMethodType mMethodType;
|
BfMethodType mMethodType;
|
||||||
BfCheckedKind mCheckedKind;
|
BfCheckedKind mCheckedKind;
|
||||||
bool mHadExplicitGenericArguments;
|
bool mHadExplicitGenericArguments;
|
||||||
|
bool mHadOpenGenericArguments;
|
||||||
|
bool mHadPartialGenericArguments;
|
||||||
bool mHasVarArguments;
|
bool mHasVarArguments;
|
||||||
bool mHadVarConflictingReturnType;
|
bool mHadVarConflictingReturnType;
|
||||||
bool mBypassVirtual;
|
bool mBypassVirtual;
|
||||||
|
@ -236,9 +252,9 @@ public:
|
||||||
int GetMostSpecificType(BfType* lhs, BfType* rhs); // 0, 1, or -1
|
int GetMostSpecificType(BfType* lhs, BfType* rhs); // 0, 1, or -1
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, const StringImpl& methodName, SizedArrayImpl<BfResolvedArg>& arguments, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments);
|
BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, const StringImpl& methodName, SizedArrayImpl<BfResolvedArg>& arguments, const BfMethodGenericArguments& methodGenericArguments);
|
||||||
BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* interfaceMethodInstance, SizedArrayImpl<BfResolvedArg>& arguments, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments = NULL);
|
BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* interfaceMethodInstance, SizedArrayImpl<BfResolvedArg>& arguments, const BfMethodGenericArguments& methodGenericArguments);
|
||||||
void Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments);
|
void Init(const BfMethodGenericArguments& methodGenericArguments);
|
||||||
bool IsMemberAccessible(BfTypeInstance* typeInst, BfTypeDef* declaringType);
|
bool IsMemberAccessible(BfTypeInstance* typeInst, BfTypeDef* declaringType);
|
||||||
bool CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass, bool forceOuterCheck = false);
|
bool CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass, bool forceOuterCheck = false);
|
||||||
void CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, bool isFailurePass);
|
void CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, bool isFailurePass);
|
||||||
|
@ -462,16 +478,16 @@ public:
|
||||||
BfResolvedArgs& argValues, bool callCtorBodyOnly, bool allowAppendAlloc, BfTypedValue* appendIndexValue = NULL);
|
BfResolvedArgs& argValues, bool callCtorBodyOnly, bool allowAppendAlloc, BfTypedValue* appendIndexValue = NULL);
|
||||||
BfTypedValue CheckEnumCreation(BfAstNode* targetSrc, BfTypeInstance* enumType, const StringImpl& caseName, BfResolvedArgs& argValues);
|
BfTypedValue CheckEnumCreation(BfAstNode* targetSrc, BfTypeInstance* enumType, const StringImpl& caseName, BfResolvedArgs& argValues);
|
||||||
BfTypedValue MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& name,
|
BfTypedValue MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& name,
|
||||||
BfResolvedArgs& argValue, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments, BfCheckedKind checkedKind = BfCheckedKind_NotSet);
|
BfResolvedArgs& argValue, const BfMethodGenericArguments& methodGenericArguments, BfCheckedKind checkedKind = BfCheckedKind_NotSet);
|
||||||
BfTypedValue MakeCallableTarget(BfAstNode* targetSrc, BfTypedValue target);
|
BfTypedValue MakeCallableTarget(BfAstNode* targetSrc, BfTypedValue target);
|
||||||
BfModuleMethodInstance GetSelectedMethod(BfAstNode* targetSrc, BfTypeInstance* curTypeInst, BfMethodDef* methodDef, BfMethodMatcher& methodMatcher, BfType** overrideReturnType = NULL);
|
BfModuleMethodInstance GetSelectedMethod(BfAstNode* targetSrc, BfTypeInstance* curTypeInst, BfMethodDef* methodDef, BfMethodMatcher& methodMatcher, BfType** overrideReturnType = NULL);
|
||||||
BfModuleMethodInstance GetSelectedMethod(BfMethodMatcher& methodMatcher);
|
BfModuleMethodInstance GetSelectedMethod(BfMethodMatcher& methodMatcher);
|
||||||
bool CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail);
|
bool CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail);
|
||||||
bool HasVariableDeclaration(BfAstNode* checkNode);
|
bool HasVariableDeclaration(BfAstNode* checkNode);
|
||||||
void DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray<BfExpression*>& args, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArgs, BfTypedValue* outCascadeValue = NULL);
|
void DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray<BfExpression*>& args, const BfMethodGenericArguments& methodGenericArgs, BfTypedValue* outCascadeValue = NULL);
|
||||||
int GetMixinVariable();
|
int GetMixinVariable();
|
||||||
void CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* typeInstance, const StringImpl& methodName, BfMethodMatcher& methodMatcher, BfMethodType methodType);
|
void CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* typeInstance, const StringImpl& methodName, BfMethodMatcher& methodMatcher, BfMethodType methodType);
|
||||||
void InjectMixin(BfAstNode* targetSrc, BfTypedValue target, bool allowImplicitThis, const StringImpl& name, const BfSizedArray<BfExpression*>& arguments, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArgs);
|
void InjectMixin(BfAstNode* targetSrc, BfTypedValue target, bool allowImplicitThis, const StringImpl& name, const BfSizedArray<BfExpression*>& arguments, const BfMethodGenericArguments& methodGenericArgs);
|
||||||
void SetMethodElementType(BfAstNode* target);
|
void SetMethodElementType(BfAstNode* target);
|
||||||
BfTypedValue DoImplicitArgCapture(BfAstNode* refNode, BfIdentifierNode* identifierNode, int shadowIdx);
|
BfTypedValue DoImplicitArgCapture(BfAstNode* refNode, BfIdentifierNode* identifierNode, int shadowIdx);
|
||||||
BfTypedValue DoImplicitArgCapture(BfAstNode* refNode, BfMethodInstance* methodInstance, int paramIdx, bool& failed, BfImplicitParamKind paramKind = BfImplicitParamKind_General, const BfTypedValue& methodRefTarget = BfTypedValue());
|
BfTypedValue DoImplicitArgCapture(BfAstNode* refNode, BfMethodInstance* methodInstance, int paramIdx, bool& failed, BfImplicitParamKind paramKind = BfImplicitParamKind_General, const BfTypedValue& methodRefTarget = BfTypedValue());
|
||||||
|
|
|
@ -8733,7 +8733,7 @@ BfIRValue BfModule::AllocBytes(BfAstNode* refNode, const BfAllocTarget& allocTar
|
||||||
if (allocTarget.mScopedInvocationTarget != NULL)
|
if (allocTarget.mScopedInvocationTarget != NULL)
|
||||||
{
|
{
|
||||||
SizedArray<BfTypeReference*, 2> genericArgs;
|
SizedArray<BfTypeReference*, 2> genericArgs;
|
||||||
exprEvaluator.DoInvocation(allocTarget.mScopedInvocationTarget, NULL, argExprs, NULL);
|
exprEvaluator.DoInvocation(allocTarget.mScopedInvocationTarget, NULL, argExprs, BfMethodGenericArguments());
|
||||||
allocResult = LoadValue(exprEvaluator.mResult);
|
allocResult = LoadValue(exprEvaluator.mResult);
|
||||||
}
|
}
|
||||||
else if (allocTarget.mCustomAllocator)
|
else if (allocTarget.mCustomAllocator)
|
||||||
|
@ -8779,7 +8779,7 @@ BfIRValue BfModule::AllocBytes(BfAstNode* refNode, const BfAllocTarget& allocTar
|
||||||
BfResolvedArgs argValues(&sizedArgExprs);
|
BfResolvedArgs argValues(&sizedArgExprs);
|
||||||
exprEvaluator.ResolveArgValues(argValues);
|
exprEvaluator.ResolveArgValues(argValues);
|
||||||
SetAndRestoreValue<bool> prevNoBind(mCurMethodState->mNoBind, true);
|
SetAndRestoreValue<bool> prevNoBind(mCurMethodState->mNoBind, true);
|
||||||
allocResult = exprEvaluator.MatchMethod(refNode, NULL, allocTarget.mCustomAllocator, false, false, allocMethodName, argValues, NULL);
|
allocResult = exprEvaluator.MatchMethod(refNode, NULL, allocTarget.mCustomAllocator, false, false, allocMethodName, argValues, BfMethodGenericArguments());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8854,7 +8854,7 @@ BfIRValue BfModule::GetMarkFuncPtr(BfType* type)
|
||||||
BfResolvedArg resolvedArg;
|
BfResolvedArg resolvedArg;
|
||||||
resolvedArg.mTypedValue = BfTypedValue(mBfIRBuilder->GetFakeVal(), type, type->IsComposite());
|
resolvedArg.mTypedValue = BfTypedValue(mBfIRBuilder->GetFakeVal(), type, type->IsComposite());
|
||||||
resolvedArgs.Add(resolvedArg);
|
resolvedArgs.Add(resolvedArg);
|
||||||
BfMethodMatcher methodMatcher(NULL, this, "Mark", resolvedArgs, NULL);
|
BfMethodMatcher methodMatcher(NULL, this, "Mark", resolvedArgs, BfMethodGenericArguments());
|
||||||
methodMatcher.CheckType(gcType, BfTypedValue(), false);
|
methodMatcher.CheckType(gcType, BfTypedValue(), false);
|
||||||
|
|
||||||
BfModuleMethodInstance moduleMethodInst = exprEvaluator.GetSelectedMethod(NULL, methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher);
|
BfModuleMethodInstance moduleMethodInst = exprEvaluator.GetSelectedMethod(NULL, methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher);
|
||||||
|
@ -9457,7 +9457,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
||||||
BfResolvedArgs argValues(&sizedArgExprs);
|
BfResolvedArgs argValues(&sizedArgExprs);
|
||||||
exprEvaluator.ResolveArgValues(argValues);
|
exprEvaluator.ResolveArgValues(argValues);
|
||||||
exprEvaluator.mNoBind = true;
|
exprEvaluator.mNoBind = true;
|
||||||
BfTypedValue allocResult = exprEvaluator.MatchMethod(allocTarget.mRefNode, NULL, allocTarget.mCustomAllocator, false, false, "AllocObject", argValues, NULL);
|
BfTypedValue allocResult = exprEvaluator.MatchMethod(allocTarget.mRefNode, NULL, allocTarget.mCustomAllocator, false, false, "AllocObject", argValues, BfMethodGenericArguments());
|
||||||
if (allocResult)
|
if (allocResult)
|
||||||
{
|
{
|
||||||
if ((allocResult.mType->IsVoidPtr()) || (allocResult.mType == mContext->mBfObjectType))
|
if ((allocResult.mType->IsVoidPtr()) || (allocResult.mType == mContext->mBfObjectType))
|
||||||
|
@ -11734,7 +11734,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
autoComplete->CheckInvocation(attributesDirective, attributesDirective->mCtorOpenParen, attributesDirective->mCtorCloseParen, attributesDirective->mCommas);
|
autoComplete->CheckInvocation(attributesDirective, attributesDirective->mCtorOpenParen, attributesDirective->mCtorCloseParen, attributesDirective->mCommas);
|
||||||
}
|
}
|
||||||
|
|
||||||
BfMethodMatcher methodMatcher(attributesDirective, this, "", argValues, NULL);
|
BfMethodMatcher methodMatcher(attributesDirective, this, "", argValues, BfMethodGenericArguments());
|
||||||
attrTypeDef = attrTypeInst->mTypeDef;
|
attrTypeDef = attrTypeInst->mTypeDef;
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
@ -17688,7 +17688,7 @@ void BfModule::EmitTupleToStringBody()
|
||||||
{
|
{
|
||||||
BfExprEvaluator exprEvaluator(this);
|
BfExprEvaluator exprEvaluator(this);
|
||||||
SizedArray<BfResolvedArg, 0> resolvedArgs;
|
SizedArray<BfResolvedArg, 0> resolvedArgs;
|
||||||
BfMethodMatcher methodMatcher(NULL, this, printModuleMethodInstance.mMethodInstance, resolvedArgs);
|
BfMethodMatcher methodMatcher(NULL, this, printModuleMethodInstance.mMethodInstance, resolvedArgs, BfMethodGenericArguments());
|
||||||
methodMatcher.mBestMethodDef = printModuleMethodInstance.mMethodInstance->mMethodDef;
|
methodMatcher.mBestMethodDef = printModuleMethodInstance.mMethodInstance->mMethodDef;
|
||||||
methodMatcher.mBestMethodTypeInstance = iPrintableType;
|
methodMatcher.mBestMethodTypeInstance = iPrintableType;
|
||||||
methodMatcher.TryDevirtualizeCall(fieldValue);
|
methodMatcher.TryDevirtualizeCall(fieldValue);
|
||||||
|
@ -17720,7 +17720,7 @@ void BfModule::EmitTupleToStringBody()
|
||||||
|
|
||||||
BfExprEvaluator exprEvaluator(this);
|
BfExprEvaluator exprEvaluator(this);
|
||||||
SizedArray<BfResolvedArg, 0> resolvedArgs;
|
SizedArray<BfResolvedArg, 0> resolvedArgs;
|
||||||
BfMethodMatcher methodMatcher(NULL, this, toStringModuleMethodInstance.mMethodInstance, resolvedArgs);
|
BfMethodMatcher methodMatcher(NULL, this, toStringModuleMethodInstance.mMethodInstance, resolvedArgs, BfMethodGenericArguments());
|
||||||
methodMatcher.mBestMethodDef = toStringModuleMethodInstance.mMethodInstance->mMethodDef;
|
methodMatcher.mBestMethodDef = toStringModuleMethodInstance.mMethodInstance->mMethodDef;
|
||||||
methodMatcher.mBestMethodTypeInstance = mContext->mBfObjectType;
|
methodMatcher.mBestMethodTypeInstance = mContext->mBfObjectType;
|
||||||
methodMatcher.TryDevirtualizeCall(fieldValue);
|
methodMatcher.TryDevirtualizeCall(fieldValue);
|
||||||
|
|
|
@ -12739,7 +12739,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
resolvedArg.mTypedValue.mKind = BfTypedValueKind_Value;
|
resolvedArg.mTypedValue.mKind = BfTypedValueKind_Value;
|
||||||
}
|
}
|
||||||
args.push_back(resolvedArg);
|
args.push_back(resolvedArg);
|
||||||
BfMethodMatcher methodMatcher(srcNode, this, "", args, NULL);
|
BfMethodMatcher methodMatcher(srcNode, this, "", args, BfMethodGenericArguments());
|
||||||
methodMatcher.mCheckReturnType = toType;
|
methodMatcher.mCheckReturnType = toType;
|
||||||
methodMatcher.mBfEvalExprFlags = (BfEvalExprFlags)(BfEvalExprFlags_NoAutoComplete | BfEvalExprFlags_FromConversionOp);
|
methodMatcher.mBfEvalExprFlags = (BfEvalExprFlags)(BfEvalExprFlags_NoAutoComplete | BfEvalExprFlags_FromConversionOp);
|
||||||
if ((castFlags & BfCastFlags_Explicit) != 0)
|
if ((castFlags & BfCastFlags_Explicit) != 0)
|
||||||
|
|
|
@ -742,7 +742,7 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int*
|
||||||
if (auto prevToken = BfNodeDynCast<BfTokenNode>(prevNode))
|
if (auto prevToken = BfNodeDynCast<BfTokenNode>(prevNode))
|
||||||
{
|
{
|
||||||
// If this is just a 'loose' comma then it can't be part of a nullable
|
// If this is just a 'loose' comma then it can't be part of a nullable
|
||||||
if ((prevToken->GetToken() == BfToken_Comma) ||
|
if (((prevToken->GetToken() == BfToken_Comma) && (chevronDepth == 0)) ||
|
||||||
(prevToken->GetToken() == BfToken_LParen))
|
(prevToken->GetToken() == BfToken_LParen))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -936,6 +936,11 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int*
|
||||||
{
|
{
|
||||||
if (checkNode->IsExact<BfLiteralExpression>())
|
if (checkNode->IsExact<BfLiteralExpression>())
|
||||||
mayBeExprPart = true;
|
mayBeExprPart = true;
|
||||||
|
else if (auto tokenNode = BfNodeDynCast<BfTokenNode>(checkNode))
|
||||||
|
{
|
||||||
|
if (tokenNode->mToken == BfToken_Question)
|
||||||
|
mayBeExprPart = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mayBeExprPart)
|
if (!mayBeExprPart)
|
||||||
|
@ -2726,7 +2731,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
|
||||||
if (auto outToken = BfNodeDynCast<BfTokenNode>(outNode))
|
if (auto outToken = BfNodeDynCast<BfTokenNode>(outNode))
|
||||||
{
|
{
|
||||||
int endNodeIdx = -1;
|
int endNodeIdx = -1;
|
||||||
if ((outToken->GetToken() == BfToken_LParen) && (IsTypeReference(exprLeft, BfToken_LParen, &endNodeIdx)))
|
if (((outToken->mToken == BfToken_LParen) && (IsTypeReference(exprLeft, BfToken_LParen, &endNodeIdx))) ||
|
||||||
|
(outToken->mToken == BfToken_DotDotDot))
|
||||||
{
|
{
|
||||||
exprLeft = CreateInvocationExpression(exprLeft);
|
exprLeft = CreateInvocationExpression(exprLeft);
|
||||||
if (exprLeft == NULL)
|
if (exprLeft == NULL)
|
||||||
|
@ -7352,7 +7358,7 @@ BfInvocationExpression* BfReducer::CreateInvocationExpression(BfAstNode* target,
|
||||||
|
|
||||||
if (tokenNode->GetToken() == BfToken_LChevron)
|
if (tokenNode->GetToken() == BfToken_LChevron)
|
||||||
{
|
{
|
||||||
auto genericParamsDecl = CreateGenericArguments(tokenNode);
|
auto genericParamsDecl = CreateGenericArguments(tokenNode, true);
|
||||||
MEMBER_SET_CHECKED(invocationExpr, mGenericArgs, genericParamsDecl);
|
MEMBER_SET_CHECKED(invocationExpr, mGenericArgs, genericParamsDecl);
|
||||||
tokenNode = ExpectTokenAfter(invocationExpr, BfToken_LParen);
|
tokenNode = ExpectTokenAfter(invocationExpr, BfToken_LParen);
|
||||||
}
|
}
|
||||||
|
@ -9726,7 +9732,7 @@ bool BfReducer::ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayIm
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfGenericArgumentsNode* BfReducer::CreateGenericArguments(BfTokenNode* tokenNode)
|
BfGenericArgumentsNode* BfReducer::CreateGenericArguments(BfTokenNode* tokenNode, bool allowPartial)
|
||||||
{
|
{
|
||||||
auto genericArgs = mAlloc->Alloc<BfGenericArgumentsNode>();
|
auto genericArgs = mAlloc->Alloc<BfGenericArgumentsNode>();
|
||||||
BfDeferredAstSizedArray<BfAstNode*> genericArgsArray(genericArgs->mGenericArgs, mAlloc);
|
BfDeferredAstSizedArray<BfAstNode*> genericArgsArray(genericArgs->mGenericArgs, mAlloc);
|
||||||
|
@ -9740,6 +9746,11 @@ BfGenericArgumentsNode* BfReducer::CreateGenericArguments(BfTokenNode* tokenNode
|
||||||
auto nextNode = mVisitorPos.GetNext();
|
auto nextNode = mVisitorPos.GetNext();
|
||||||
if (BfNodeIsA<BfLiteralExpression>(nextNode))
|
if (BfNodeIsA<BfLiteralExpression>(nextNode))
|
||||||
doAsExpr = true;
|
doAsExpr = true;
|
||||||
|
else if (auto tokenNode = BfNodeDynCast<BfTokenNode>(nextNode))
|
||||||
|
{
|
||||||
|
if (tokenNode->mToken == BfToken_Question)
|
||||||
|
doAsExpr = true;
|
||||||
|
}
|
||||||
|
|
||||||
BfAstNode* genericArg = NULL;
|
BfAstNode* genericArg = NULL;
|
||||||
if (doAsExpr)
|
if (doAsExpr)
|
||||||
|
@ -9782,6 +9793,15 @@ BfGenericArgumentsNode* BfReducer::CreateGenericArguments(BfTokenNode* tokenNode
|
||||||
if (token == BfToken_RDblChevron)
|
if (token == BfToken_RDblChevron)
|
||||||
tokenNode = BreakDoubleChevron(tokenNode);
|
tokenNode = BreakDoubleChevron(tokenNode);
|
||||||
|
|
||||||
|
if ((token == BfToken_DotDotDot) && (allowPartial))
|
||||||
|
{
|
||||||
|
commas.push_back(tokenNode);
|
||||||
|
mVisitorPos.MoveNext();
|
||||||
|
nextNode = mVisitorPos.GetNext();
|
||||||
|
tokenNode = BfNodeDynCast<BfTokenNode>(nextNode);
|
||||||
|
token = tokenNode->GetToken();
|
||||||
|
}
|
||||||
|
|
||||||
if (token == BfToken_RChevron)
|
if (token == BfToken_RChevron)
|
||||||
{
|
{
|
||||||
MoveNode(tokenNode, genericArgs);
|
MoveNode(tokenNode, genericArgs);
|
||||||
|
|
|
@ -226,7 +226,7 @@ public:
|
||||||
BfTypeReference* CreateTypeRefAfter(BfAstNode* astNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None);
|
BfTypeReference* CreateTypeRefAfter(BfAstNode* astNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None);
|
||||||
BfTypeReference* CreateRefTypeRef(BfTypeReference* elementType, BfTokenNode* refToken);
|
BfTypeReference* CreateRefTypeRef(BfTypeReference* elementType, BfTokenNode* refToken);
|
||||||
bool ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayImpl<BfParameterDeclaration*>* params, SizedArrayImpl<BfTokenNode*>* commas, bool alwaysIncludeBlock = false);
|
bool ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayImpl<BfParameterDeclaration*>* params, SizedArrayImpl<BfTokenNode*>* commas, bool alwaysIncludeBlock = false);
|
||||||
BfGenericArgumentsNode* CreateGenericArguments(BfTokenNode* tokenNode);
|
BfGenericArgumentsNode* CreateGenericArguments(BfTokenNode* tokenNode, bool allowPartial = false);
|
||||||
BfGenericParamsDeclaration* CreateGenericParamsDeclaration(BfTokenNode* tokenNode);
|
BfGenericParamsDeclaration* CreateGenericParamsDeclaration(BfTokenNode* tokenNode);
|
||||||
BfGenericConstraintsDeclaration* CreateGenericConstraintsDeclaration(BfTokenNode* tokenNode);
|
BfGenericConstraintsDeclaration* CreateGenericConstraintsDeclaration(BfTokenNode* tokenNode);
|
||||||
BfForEachStatement* CreateForEachStatement(BfAstNode* node, bool hasTypeDecl);
|
BfForEachStatement* CreateForEachStatement(BfAstNode* node, bool hasTypeDecl);
|
||||||
|
|
|
@ -4079,7 +4079,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
|
||||||
BfResolvedArgs argValues(&sizedArgExprs);
|
BfResolvedArgs argValues(&sizedArgExprs);
|
||||||
exprEvaluator.ResolveArgValues(argValues);
|
exprEvaluator.ResolveArgValues(argValues);
|
||||||
exprEvaluator.mNoBind = true;
|
exprEvaluator.mNoBind = true;
|
||||||
exprEvaluator.MatchMethod(deleteStmt->mAllocExpr, NULL, customAllocator, false, true, "FreeObject", argValues, NULL);
|
exprEvaluator.MatchMethod(deleteStmt->mAllocExpr, NULL, customAllocator, false, true, "FreeObject", argValues, BfMethodGenericArguments());
|
||||||
customAllocator = BfTypedValue();
|
customAllocator = BfTypedValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4137,7 +4137,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
|
||||||
BfResolvedArgs argValues(&sizedArgExprs);
|
BfResolvedArgs argValues(&sizedArgExprs);
|
||||||
exprEvaluator.ResolveArgValues(argValues);
|
exprEvaluator.ResolveArgValues(argValues);
|
||||||
exprEvaluator.mNoBind = true;
|
exprEvaluator.mNoBind = true;
|
||||||
exprEvaluator.MatchMethod(deleteStmt->mAllocExpr, NULL, customAllocator, false, false, "Free", argValues, NULL);
|
exprEvaluator.MatchMethod(deleteStmt->mAllocExpr, NULL, customAllocator, false, false, "Free", argValues, BfMethodGenericArguments());
|
||||||
}
|
}
|
||||||
|
|
||||||
mBfIRBuilder->CreateBr(endBB);
|
mBfIRBuilder->CreateBr(endBB);
|
||||||
|
@ -5444,7 +5444,7 @@ void BfModule::Visit(BfUsingStatement* usingStmt)
|
||||||
|
|
||||||
exprEvaluator.mFunctionBindResult = &functionBindResult;
|
exprEvaluator.mFunctionBindResult = &functionBindResult;
|
||||||
SizedArray<BfResolvedArg, 0> resolvedArgs;
|
SizedArray<BfResolvedArg, 0> resolvedArgs;
|
||||||
BfMethodMatcher methodMatcher(usingStmt->mVariableDeclaration, this, dispMethod.mMethodInstance, resolvedArgs);
|
BfMethodMatcher methodMatcher(usingStmt->mVariableDeclaration, this, dispMethod.mMethodInstance, resolvedArgs, BfMethodGenericArguments());
|
||||||
methodMatcher.CheckType(iDisposableType, embeddedValue, false);
|
methodMatcher.CheckType(iDisposableType, embeddedValue, false);
|
||||||
methodMatcher.TryDevirtualizeCall(embeddedValue);
|
methodMatcher.TryDevirtualizeCall(embeddedValue);
|
||||||
auto retVal = exprEvaluator.CreateCall(&methodMatcher, embeddedValue);
|
auto retVal = exprEvaluator.CreateCall(&methodMatcher, embeddedValue);
|
||||||
|
@ -6528,7 +6528,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
|
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
|
||||||
BfResolvedArgs resolvedArgs;
|
BfResolvedArgs resolvedArgs;
|
||||||
exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete);
|
exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete);
|
||||||
exprEvaluator.MatchMethod(forEachStmt->mCollectionExpression, NULL, itr, false, false, "Dispose", resolvedArgs, NULL);
|
exprEvaluator.MatchMethod(forEachStmt->mCollectionExpression, NULL, itr, false, false, "Dispose", resolvedArgs, BfMethodGenericArguments());
|
||||||
if (functionBindResult.mMethodInstance != NULL)
|
if (functionBindResult.mMethodInstance != NULL)
|
||||||
{
|
{
|
||||||
BfModuleMethodInstance moduleMethodInstance;
|
BfModuleMethodInstance moduleMethodInstance;
|
||||||
|
@ -6624,7 +6624,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
BfExprEvaluator exprEvaluator(this);
|
BfExprEvaluator exprEvaluator(this);
|
||||||
auto itrTypeInstance = itr.mType->ToTypeInstance();
|
auto itrTypeInstance = itr.mType->ToTypeInstance();
|
||||||
SizedArray<BfResolvedArg, 0> resolvedArgs;
|
SizedArray<BfResolvedArg, 0> resolvedArgs;
|
||||||
BfMethodMatcher methodMatcher(forEachStmt->mCollectionExpression, this, getNextMethodInst.mMethodInstance, resolvedArgs);
|
BfMethodMatcher methodMatcher(forEachStmt->mCollectionExpression, this, getNextMethodInst.mMethodInstance, resolvedArgs, BfMethodGenericArguments());
|
||||||
if (isRefExpression)
|
if (isRefExpression)
|
||||||
methodMatcher.CheckType(refItrInterface, itr, false);
|
methodMatcher.CheckType(refItrInterface, itr, false);
|
||||||
else
|
else
|
||||||
|
@ -6704,7 +6704,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
if (typeOptions != NULL)
|
if (typeOptions != NULL)
|
||||||
boundsCheck = typeOptions->Apply(boundsCheck, BfOptionFlags_RuntimeChecks);
|
boundsCheck = typeOptions->Apply(boundsCheck, BfOptionFlags_RuntimeChecks);
|
||||||
|
|
||||||
BfMethodMatcher methodMatcher(forEachStmt->mVariableName, this, "get__", argValues.mResolvedArgs, NULL);
|
BfMethodMatcher methodMatcher(forEachStmt->mVariableName, this, "get__", argValues.mResolvedArgs, BfMethodGenericArguments());
|
||||||
methodMatcher.mMethodType = BfMethodType_PropertyGetter;
|
methodMatcher.mMethodType = BfMethodType_PropertyGetter;
|
||||||
methodMatcher.CheckType(target.mType->ToTypeInstance(), target, false);
|
methodMatcher.CheckType(target.mType->ToTypeInstance(), target, false);
|
||||||
if (methodMatcher.mBestMethodDef == NULL)
|
if (methodMatcher.mBestMethodDef == NULL)
|
||||||
|
@ -6957,7 +6957,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
||||||
exprEvaluator.ResolveArgValues(argValues);
|
exprEvaluator.ResolveArgValues(argValues);
|
||||||
exprEvaluator.mNoBind = true;
|
exprEvaluator.mNoBind = true;
|
||||||
exprEvaluator.mFunctionBindResult = &functionBindResult;
|
exprEvaluator.mFunctionBindResult = &functionBindResult;
|
||||||
exprEvaluator.MatchMethod(deleteStmt->mAllocExpr, NULL, customAllocator, false, false, "FreeObject", argValues, NULL);
|
exprEvaluator.MatchMethod(deleteStmt->mAllocExpr, NULL, customAllocator, false, false, "FreeObject", argValues, BfMethodGenericArguments());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -6973,7 +6973,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
||||||
exprEvaluator.ResolveArgValues(argValues);
|
exprEvaluator.ResolveArgValues(argValues);
|
||||||
exprEvaluator.mNoBind = true;
|
exprEvaluator.mNoBind = true;
|
||||||
exprEvaluator.mFunctionBindResult = &functionBindResult;
|
exprEvaluator.mFunctionBindResult = &functionBindResult;
|
||||||
exprEvaluator.MatchMethod(deleteStmt->mAllocExpr, NULL, customAllocator, false, false, "Free", argValues, NULL);
|
exprEvaluator.MatchMethod(deleteStmt->mAllocExpr, NULL, customAllocator, false, false, "Free", argValues, BfMethodGenericArguments());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (functionBindResult.mMethodInstance != NULL)
|
if (functionBindResult.mMethodInstance != NULL)
|
||||||
|
|
|
@ -326,6 +326,11 @@ namespace Tests
|
||||||
TestGen(a);
|
TestGen(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TOut Conv<TOut, TIn>(TIn val) where TOut : operator explicit TIn
|
||||||
|
{
|
||||||
|
return (TOut)val;
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -396,6 +401,9 @@ namespace Tests
|
||||||
true
|
true
|
||||||
} == false);
|
} == false);
|
||||||
MethodG<ClassG, ClassF>();
|
MethodG<ClassG, ClassF>();
|
||||||
|
|
||||||
|
Test.Assert(Conv<int...>(12.34f) == 12);
|
||||||
|
Test.Assert(Conv<int,?>(12.34f) == 12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue