mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Generic constructors
This commit is contained in:
parent
64d646e130
commit
04ea8a6634
13 changed files with 267 additions and 37 deletions
|
@ -116,6 +116,11 @@ void BfStructuralVisitor::Visit(BfGenericArgumentsNode* genericArgumentsNode)
|
|||
Visit(genericArgumentsNode->ToBase());
|
||||
}
|
||||
|
||||
void BfStructuralVisitor::Visit(BfCtorExplicitNode* ctorExplicitNode)
|
||||
{
|
||||
Visit(ctorExplicitNode->ToBase());
|
||||
}
|
||||
|
||||
void BfStructuralVisitor::Visit(BfStatement* stmt)
|
||||
{
|
||||
Visit(stmt->ToBase());
|
||||
|
|
|
@ -337,6 +337,7 @@ class BfScopeNode;
|
|||
class BfNewNode;
|
||||
class BfLabeledBlock;
|
||||
class BfGenericArgumentsNode;
|
||||
class BfCtorExplicitNode;
|
||||
class BfStatement;
|
||||
class BfLabelableStatement;
|
||||
class BfExpression;
|
||||
|
@ -529,6 +530,7 @@ public:
|
|||
virtual void Visit(BfGenericOperatorConstraint* genericConstraints);
|
||||
virtual void Visit(BfGenericConstraintsDeclaration* genericConstraints);
|
||||
virtual void Visit(BfGenericArgumentsNode* genericArgumentsNode);
|
||||
virtual void Visit(BfCtorExplicitNode* genericArgumentsNode);
|
||||
|
||||
virtual void Visit(BfEmptyStatement* emptyStmt);
|
||||
virtual void Visit(BfTokenNode* tokenNode);
|
||||
|
@ -2911,6 +2913,16 @@ public:
|
|||
BfAstNode* mStatement;
|
||||
}; BF_AST_DECL(BfAttributedStatement, BfStatement);
|
||||
|
||||
class BfCtorExplicitNode : public BfAstNode
|
||||
{
|
||||
public:
|
||||
BF_AST_TYPE(BfCtorExplicitNode, BfAstNode);
|
||||
|
||||
BfAstNode* mDotToken;
|
||||
BfTokenNode* mThisToken;
|
||||
BfGenericArgumentsNode* mGenericArgs;
|
||||
}; BF_AST_DECL(BfCtorExplicitNode, BfAstNode);
|
||||
|
||||
class BfObjectCreateExpression : public BfMethodBoundExpression
|
||||
{
|
||||
public:
|
||||
|
@ -2919,6 +2931,7 @@ public:
|
|||
BfAstNode* mNewNode;
|
||||
BfTokenNode* mStarToken;
|
||||
BfTypeReference* mTypeRef;
|
||||
BfCtorExplicitNode* mCtorExplicit;
|
||||
BfTokenNode* mOpenToken;
|
||||
BfTokenNode* mCloseToken;
|
||||
BfSizedArray<BfExpression*> mArguments;
|
||||
|
|
|
@ -604,7 +604,8 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
|
|||
if ((methodDef->mMethodType == BfMethodType_Normal) ||
|
||||
(methodDef->mMethodType == BfMethodType_Operator) ||
|
||||
(methodDef->mMethodType == BfMethodType_Mixin) ||
|
||||
(methodDef->mMethodType == BfMethodType_Extension))
|
||||
(methodDef->mMethodType == BfMethodType_Extension) ||
|
||||
(methodDef->mMethodType == BfMethodType_Ctor))
|
||||
{
|
||||
bool isGeneric = (methodDeclaration->mGenericParams != NULL) || (!mCurTypeDef->mGenericParamDefs.IsEmpty());
|
||||
ParseGenericParams(methodDeclaration->mGenericParams, methodDeclaration->mGenericConstraintsDeclaration, methodDef->mGenericParams, &methodDef->mExternalConstraints, outerGenericSize, isGeneric);
|
||||
|
@ -2085,6 +2086,14 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
methodDef->mParams.push_back(newParam);
|
||||
}
|
||||
|
||||
for (auto genericParam : method->mGenericParams)
|
||||
{
|
||||
BfGenericParamDef* newGenericParam = new BfGenericParamDef();
|
||||
*newGenericParam = *genericParam;
|
||||
methodDef->mGenericParams.Add(newGenericParam);
|
||||
}
|
||||
methodDef->mExternalConstraints = method->mExternalConstraints;
|
||||
|
||||
// Insert a 'appendIdx'
|
||||
BfParameterDef* newParam = new BfParameterDef();
|
||||
newParam->mName = "appendIdx";
|
||||
|
|
|
@ -114,6 +114,15 @@ void BfElementVisitor::Visit(BfGenericArgumentsNode* genericArgumentsNode)
|
|||
VisitChild(genericArgumentsNode->mCloseChevron);
|
||||
}
|
||||
|
||||
void BfElementVisitor::Visit(BfCtorExplicitNode* ctorExplicitNode)
|
||||
{
|
||||
Visit(ctorExplicitNode->ToBase());
|
||||
|
||||
VisitChild(ctorExplicitNode->mDotToken);
|
||||
VisitChild(ctorExplicitNode->mThisToken);
|
||||
VisitChild(ctorExplicitNode->mGenericArgs);
|
||||
}
|
||||
|
||||
void BfElementVisitor::Visit(BfStatement* stmt)
|
||||
{
|
||||
Visit(stmt->ToBase());
|
||||
|
@ -627,6 +636,7 @@ void BfElementVisitor::Visit(BfObjectCreateExpression* newExpr)
|
|||
VisitChild(newExpr->mNewNode);
|
||||
VisitChild(newExpr->mStarToken);
|
||||
VisitChild(newExpr->mTypeRef);
|
||||
VisitChild(newExpr->mCtorExplicit);
|
||||
VisitChild(newExpr->mOpenToken);
|
||||
VisitChild(newExpr->mCloseToken);
|
||||
for (auto& val : newExpr->mArguments)
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
virtual void Visit(BfGenericOperatorConstraint* genericConstraints);
|
||||
virtual void Visit(BfGenericConstraintsDeclaration* genericConstraints);
|
||||
virtual void Visit(BfGenericArgumentsNode* genericArgumentsNode);
|
||||
virtual void Visit(BfCtorExplicitNode* genericArgumentsNode);
|
||||
|
||||
virtual void Visit(BfEmptyStatement* emptyStmt);
|
||||
virtual void Visit(BfTokenNode* tokenNode);
|
||||
|
|
|
@ -7977,7 +7977,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
arrayType, false);
|
||||
|
||||
BfResolvedArgs resolvedArgs;
|
||||
MatchConstructor(targetSrc, NULL, expandedParamsArray, arrayType, resolvedArgs, false, false);
|
||||
MatchConstructor(targetSrc, NULL, expandedParamsArray, arrayType, resolvedArgs, false, BfMethodGenericArguments(), false);
|
||||
|
||||
//TODO: Assert 'length' var is at slot 1
|
||||
auto arrayBits = mModule->mBfIRBuilder->CreateBitCast(expandedParamsArray.mValue, mModule->mBfIRBuilder->MapType(arrayType->mBaseType));
|
||||
|
@ -8742,7 +8742,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
return callResult;
|
||||
}
|
||||
|
||||
BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType, BfResolvedArgs& argValues, bool callCtorBodyOnly, bool allowAppendAlloc, BfTypedValue* appendIndexValue)
|
||||
BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType, BfResolvedArgs& argValues, bool callCtorBodyOnly,
|
||||
const BfMethodGenericArguments& methodGenericArguments, bool allowAppendAlloc, BfTypedValue* appendIndexValue)
|
||||
{
|
||||
// Temporarily disable so we don't capture calls in params
|
||||
SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
|
||||
|
@ -8750,7 +8751,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
|||
static int sCtorCount = 0;
|
||||
sCtorCount++;
|
||||
|
||||
BfMethodMatcher methodMatcher(targetSrc, mModule, "", argValues.mResolvedArgs, BfMethodGenericArguments());
|
||||
BfMethodMatcher methodMatcher(targetSrc, mModule, "", argValues.mResolvedArgs, methodGenericArguments);
|
||||
methodMatcher.mBfEvalExprFlags = mBfEvalExprFlags;
|
||||
|
||||
BfTypeVector typeGenericArguments;
|
||||
|
@ -8842,11 +8843,13 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
|||
// There should always be a constructor
|
||||
BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
|
||||
|
||||
auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher.mBestMethodGenericArguments);
|
||||
if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc))
|
||||
{
|
||||
//auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher.mBestMethodGenericArguments);
|
||||
|
||||
auto moduleMethodInstance = GetSelectedMethod(methodMatcher);
|
||||
if (!moduleMethodInstance)
|
||||
return BfTypedValue();
|
||||
}
|
||||
if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc))
|
||||
return BfTypedValue();
|
||||
|
||||
BfAutoComplete* autoComplete = GetAutoComplete();
|
||||
if (autoComplete != NULL)
|
||||
|
@ -10142,7 +10145,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
|||
mResultLocalVar = NULL;
|
||||
mResultFieldInstance = NULL;
|
||||
mResultLocalVarRefNode = NULL;
|
||||
auto result = MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, resolvedTypeInstance->IsObject());
|
||||
auto result = MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, BfMethodGenericArguments(), resolvedTypeInstance->IsObject());
|
||||
if ((result) && (!result.mType->IsVoid()))
|
||||
return result;
|
||||
mModule->ValidateAllocation(resolvedTypeInstance, targetSrc);
|
||||
|
@ -14042,7 +14045,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
}
|
||||
|
||||
BfResolvedArgs resolvedArgs;
|
||||
MatchConstructor(delegateBindExpr, delegateBindExpr, mResult, useTypeInstance, resolvedArgs, false, false);
|
||||
MatchConstructor(delegateBindExpr, delegateBindExpr, mResult, useTypeInstance, resolvedArgs, false, BfMethodGenericArguments(), false);
|
||||
|
||||
auto baseDelegateType = VerifyBaseDelegateType(delegateTypeInstance->mBaseType);
|
||||
auto baseDelegate = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(baseDelegateType, BfIRPopulateType_Full));
|
||||
|
@ -15490,6 +15493,10 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
}
|
||||
}
|
||||
|
||||
BfMethodGenericArguments methodGenericArguments;
|
||||
if ((objCreateExpr != NULL) && (objCreateExpr->mCtorExplicit != NULL) && (objCreateExpr->mCtorExplicit->mGenericArgs != NULL))
|
||||
methodGenericArguments.mArguments = &objCreateExpr->mCtorExplicit->mGenericArgs->mGenericArgs;
|
||||
|
||||
CheckObjectCreateTypeRef(mExpectingType, allocNode);
|
||||
|
||||
BfAttributeState attributeState;
|
||||
|
@ -15499,12 +15506,18 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
BfAllocTarget allocTarget;
|
||||
ResolveAllocTarget(allocTarget, allocNode, newToken, &attributeState.mCustomAttributes);
|
||||
|
||||
bool isScopeAlloc = newToken->GetToken() == BfToken_Scope;
|
||||
bool isAppendAlloc = newToken->GetToken() == BfToken_Append;
|
||||
bool isStackAlloc = (newToken->GetToken() == BfToken_Stack) || (isScopeAlloc);
|
||||
bool isStructAlloc = newToken == NULL;
|
||||
bool isScopeAlloc = (newToken != NULL) && (newToken->GetToken() == BfToken_Scope);
|
||||
bool isAppendAlloc = (newToken != NULL) && (newToken->GetToken() == BfToken_Append);
|
||||
bool isStackAlloc = ((newToken != NULL) && (newToken->GetToken() == BfToken_Stack)) || (isScopeAlloc) || (isStructAlloc);
|
||||
bool isArrayAlloc = false;// (objCreateExpr->mArraySizeSpecifier != NULL);
|
||||
bool isRawArrayAlloc = (objCreateExpr != NULL) && (objCreateExpr->mStarToken != NULL);
|
||||
|
||||
if ((objCreateExpr != NULL) && (objCreateExpr->mCtorExplicit != NULL) && (objCreateExpr->mCtorExplicit->mThisToken != NULL))
|
||||
{
|
||||
mModule->SetElementType(objCreateExpr->mCtorExplicit->mThisToken, BfSourceElementType_Method);
|
||||
}
|
||||
|
||||
if (isScopeAlloc)
|
||||
{
|
||||
if ((mBfEvalExprFlags & BfEvalExprFlags_FieldInitializer) != 0)
|
||||
|
@ -15579,6 +15592,10 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
{
|
||||
unresolvedTypeRef = mExpectingType->GetUnderlyingType();
|
||||
}
|
||||
else if (mExpectingType->IsStruct())
|
||||
{
|
||||
unresolvedTypeRef = mExpectingType;
|
||||
}
|
||||
else if (mExpectingType->IsVar())
|
||||
unresolvedTypeRef = mExpectingType;
|
||||
}
|
||||
|
@ -16107,18 +16124,18 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
BfResolvedArgs resolvedArgs;
|
||||
|
||||
auto rawAutoComplete = mModule->mCompiler->GetAutoComplete();
|
||||
if (rawAutoComplete != NULL)
|
||||
{
|
||||
SetAndRestoreValue<bool> prevCapturing(rawAutoComplete->mIsCapturingMethodMatchInfo, false);
|
||||
MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, false);
|
||||
MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, methodGenericArguments, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, false);
|
||||
MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, methodGenericArguments, false);
|
||||
}
|
||||
|
||||
//TODO: Assert 'length' var is at slot 1
|
||||
|
@ -16294,7 +16311,11 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
{
|
||||
auto wasCapturingMethodInfo = autoComplete->mIsCapturingMethodMatchInfo;
|
||||
autoComplete->CheckInvocation(objCreateExpr, objCreateExpr->mOpenToken, objCreateExpr->mCloseToken, objCreateExpr->mCommas);
|
||||
MatchConstructor(objCreateExpr->mTypeRef, objCreateExpr, emtpyThis, typeInstance, argValues, false, true);
|
||||
|
||||
BfAstNode* refNode = objCreateExpr->mTypeRef;
|
||||
if ((objCreateExpr->mCtorExplicit != NULL) && (objCreateExpr->mCtorExplicit->mThisToken != NULL))
|
||||
refNode = objCreateExpr->mCtorExplicit->mThisToken;
|
||||
MatchConstructor(refNode, objCreateExpr, emtpyThis, typeInstance, argValues, false, methodGenericArguments, true);
|
||||
if ((wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo))
|
||||
{
|
||||
if (autoComplete->mMethodMatchInfo != NULL)
|
||||
|
@ -16308,7 +16329,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
auto refNode = allocNode;
|
||||
if (objCreateExpr != NULL)
|
||||
refNode = objCreateExpr->mTypeRef;
|
||||
MatchConstructor(refNode, objCreateExpr, emtpyThis, typeInstance, argValues, false, true);
|
||||
MatchConstructor(refNode, objCreateExpr, emtpyThis, typeInstance, argValues, false, methodGenericArguments, true);
|
||||
}
|
||||
if (objCreateExpr != NULL)
|
||||
mModule->ValidateAllocation(typeInstance, objCreateExpr->mTypeRef);
|
||||
|
@ -16329,7 +16350,16 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
}
|
||||
else
|
||||
{
|
||||
auto calcAppendMethodModule = mModule->GetMethodInstanceAtIdx(bindResult.mMethodInstance->GetOwner(), bindResult.mMethodInstance->mMethodDef->mIdx + 1, BF_METHODNAME_CALCAPPEND);
|
||||
//auto calcAppendMethodModule = mModule->GetMethodInstanceAtIdx(bindResult.mMethodInstance->GetOwner(), bindResult.mMethodInstance->mMethodDef->mIdx + 1, BF_METHODNAME_CALCAPPEND);
|
||||
|
||||
BfTypeVector methodGenericArguments;
|
||||
if (bindResult.mMethodInstance->mMethodInfoEx != NULL)
|
||||
methodGenericArguments = bindResult.mMethodInstance->mMethodInfoEx->mMethodGenericArguments;
|
||||
|
||||
auto methodOwner = bindResult.mMethodInstance->GetOwner();
|
||||
auto calcAppendMethodDef = methodOwner->mTypeDef->mMethods[bindResult.mMethodInstance->mMethodDef->mIdx + 1];
|
||||
BF_ASSERT(calcAppendMethodDef->mName == BF_METHODNAME_CALCAPPEND);
|
||||
auto calcAppendMethodModule = mModule->GetMethodInstance(methodOwner, calcAppendMethodDef, methodGenericArguments);
|
||||
|
||||
SizedArray<BfIRValue, 2> irArgs;
|
||||
if (bindResult.mIRArgs.size() > 1)
|
||||
|
@ -16523,6 +16553,17 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
{
|
||||
mModule->mCompiler->mCeMachine->ClearAppendAllocInfo();
|
||||
}
|
||||
|
||||
if ((mResult) && (isStructAlloc))
|
||||
{
|
||||
if (mResult.mType->IsPointer())
|
||||
{
|
||||
mResult = mModule->LoadValue(mResult);
|
||||
mResult = BfTypedValue(mResult.mValue, mResult.mType->GetUnderlyingType(), true);
|
||||
}
|
||||
else
|
||||
mModule->Fail(StrFormat("Allocation specifier such as 'new' is required for reference type '%s'", mModule->TypeToString(mResult.mType).c_str()), objCreateExpr);
|
||||
}
|
||||
}
|
||||
|
||||
void BfExprEvaluator::Visit(BfBoxExpression* boxExpr)
|
||||
|
@ -16612,7 +16653,13 @@ void BfExprEvaluator::ResolveAllocTarget(BfAllocTarget& allocTarget, BfAstNode*
|
|||
|
||||
allocTarget.mRefNode = allocNode;
|
||||
newToken = BfNodeDynCast<BfTokenNode>(allocNode);
|
||||
if (newToken == NULL)
|
||||
if (allocNode == NULL)
|
||||
{
|
||||
// Scope
|
||||
if (mModule->mCurMethodState != NULL)
|
||||
allocTarget.mScopeData = mModule->mCurMethodState->mCurScope->GetTargetable();
|
||||
}
|
||||
else if (newToken == NULL)
|
||||
{
|
||||
if (auto scopeNode = BfNodeDynCast<BfScopeNode>(allocNode))
|
||||
{
|
||||
|
@ -18269,7 +18316,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
|||
else
|
||||
mResult = BfTypedValue(mModule->CreateAlloca(expectingType), expectingType, BfTypedValueKind_TempAddr);
|
||||
|
||||
auto ctorResult = MatchConstructor(target, methodBoundExpr, mResult, expectingType->ToTypeInstance(), argValues, false, false);
|
||||
auto ctorResult = MatchConstructor(target, methodBoundExpr, mResult, expectingType->ToTypeInstance(), argValues, false, BfMethodGenericArguments(), false);
|
||||
if ((ctorResult) && (!ctorResult.mType->IsVoid()))
|
||||
mResult = ctorResult;
|
||||
mModule->ValidateAllocation(expectingType, invocationExpr->mTarget);
|
||||
|
@ -23591,7 +23638,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
|
|||
ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
||||
|
||||
mResult = BfTypedValue(alloca, allocType, true);
|
||||
auto result = MatchConstructor(opToken, NULL, mResult, allocType, argValues, true, false);
|
||||
auto result = MatchConstructor(opToken, NULL, mResult, allocType, argValues, true, BfMethodGenericArguments(), false);
|
||||
if ((result) && (!result.mType->IsVoid()))
|
||||
mResult = result;
|
||||
|
||||
|
|
|
@ -497,7 +497,7 @@ public:
|
|||
void PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& irArgs, bool disableSplat = false, bool disableLowering = false, bool isIntrinsic = false, bool createCompositeCopy = false);
|
||||
void PushThis(BfAstNode* targetSrc, BfTypedValue callTarget, BfMethodInstance* methodInstance, SizedArrayImpl<BfIRValue>& irArgs, bool skipMutCheck = false);
|
||||
BfTypedValue MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType,
|
||||
BfResolvedArgs& argValues, bool callCtorBodyOnly, bool allowAppendAlloc, BfTypedValue* appendIndexValue = NULL);
|
||||
BfResolvedArgs& argValues, bool callCtorBodyOnly, const BfMethodGenericArguments& methodGenericArguments, bool allowAppendAlloc, BfTypedValue* appendIndexValue = NULL);
|
||||
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,
|
||||
BfResolvedArgs& argValue, const BfMethodGenericArguments& methodGenericArguments, BfCheckedKind checkedKind = BfCheckedKind_NotSet);
|
||||
|
|
|
@ -778,7 +778,7 @@ public:
|
|||
if (typeInst != NULL)
|
||||
{
|
||||
exprEvaluator.ResolveArgValues(argValues);
|
||||
exprEvaluator.MatchConstructor(objCreateExpr->mTypeRef, objCreateExpr, emtpyThis, typeInst, argValues, false, true);
|
||||
exprEvaluator.MatchConstructor(objCreateExpr->mTypeRef, objCreateExpr, emtpyThis, typeInst, argValues, false, BfMethodGenericArguments(), true);
|
||||
}
|
||||
exprEvaluator.mFunctionBindResult = NULL;
|
||||
|
||||
|
@ -4765,7 +4765,7 @@ void BfModule::AppendedObjectInit(BfFieldInstance* fieldInst)
|
|||
mBfIRBuilder->CreateStore(GetConstValue8(BfObjectFlag_AppendAlloc), thisFlagsPtr);
|
||||
}
|
||||
|
||||
exprEvaluator.MatchConstructor(fieldDef->GetNameNode(), NULL, thisValue, fieldInst->mResolvedType->ToTypeInstance(), resolvedArgs, false, true, &indexVal);
|
||||
exprEvaluator.MatchConstructor(fieldDef->GetNameNode(), NULL, thisValue, fieldInst->mResolvedType->ToTypeInstance(), resolvedArgs, false, BfMethodGenericArguments(), true, &indexVal);
|
||||
}
|
||||
|
||||
void BfModule::CheckInterfaceMethod(BfMethodInstance* methodInstance)
|
||||
|
@ -17149,7 +17149,7 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
|
|||
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
|
||||
exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
||||
SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(exprEvaluator.mFunctionBindResult, &bindResult);
|
||||
exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, true);
|
||||
exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, BfMethodGenericArguments(), true);
|
||||
}
|
||||
|
||||
if (bindResult.mMethodInstance == NULL)
|
||||
|
@ -17196,7 +17196,7 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
|
|||
bindResult.mSkipThis = true;
|
||||
bindResult.mWantsArgs = true;
|
||||
SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(exprEvaluator.mFunctionBindResult, &bindResult);
|
||||
exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, true);
|
||||
exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, BfMethodGenericArguments(), true);
|
||||
BF_ASSERT(bindResult.mIRArgs[0].IsFake());
|
||||
bindResult.mIRArgs.RemoveAt(0);
|
||||
calcAppendArgs = bindResult.mIRArgs;
|
||||
|
@ -18704,7 +18704,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
|||
appendIdxVal = BfTypedValue(localVar->mValue, intRefType);
|
||||
mCurMethodState->mCurAppendAlign = 1; // Don't make any assumptions about how the base leaves the alignment
|
||||
}
|
||||
exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, methodDef->mHasAppend, &appendIdxVal);
|
||||
exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, BfMethodGenericArguments(), methodDef->mHasAppend, &appendIdxVal);
|
||||
|
||||
if (autoComplete != NULL)
|
||||
{
|
||||
|
|
|
@ -5537,7 +5537,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
BfTypedValue emptyThis(mBfIRBuilder->GetFakeVal(), resolvedTypeRef, resolvedTypeRef->IsStruct());
|
||||
|
||||
exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_Comptime;
|
||||
auto ctorResult = exprEvaluator.MatchConstructor(nameRefNode, NULL, emptyThis, fieldTypeInst, resolvedArgs, false, true);
|
||||
auto ctorResult = exprEvaluator.MatchConstructor(nameRefNode, NULL, emptyThis, fieldTypeInst, resolvedArgs, false, BfMethodGenericArguments(), true);
|
||||
|
||||
if ((bindResult.mMethodInstance != NULL) && (bindResult.mMethodInstance->mMethodDef->mHasAppend))
|
||||
{
|
||||
|
|
|
@ -1913,6 +1913,7 @@ void BfPrinter::Visit(BfObjectCreateExpression* newExpr)
|
|||
ExpectSpace();
|
||||
|
||||
VisitChild(newExpr->mTypeRef);
|
||||
VisitChild(newExpr->mCtorExplicit);
|
||||
|
||||
if (newExpr->mStarToken != NULL)
|
||||
{
|
||||
|
@ -2497,6 +2498,7 @@ void BfPrinter::Visit(BfConstructorDeclaration* ctorDeclaration)
|
|||
{
|
||||
QueueVisitChild(ctorDeclaration->mThisToken);
|
||||
}
|
||||
QueueVisitChild(ctorDeclaration->mGenericParams);
|
||||
|
||||
QueueVisitChild(ctorDeclaration->mOpenParen);
|
||||
for (int i = 0; i < (int) ctorDeclaration->mParams.size(); i++)
|
||||
|
@ -2513,6 +2515,8 @@ void BfPrinter::Visit(BfConstructorDeclaration* ctorDeclaration)
|
|||
QueueVisitChild(ctorDeclaration->mInitializerColonToken);
|
||||
ExpectSpace();
|
||||
QueueVisitChild(ctorDeclaration->mInitializer);
|
||||
ExpectSpace();
|
||||
QueueVisitChild(ctorDeclaration->mGenericConstraintsDeclaration);
|
||||
|
||||
if (ctorDeclaration->mFatArrowToken != NULL)
|
||||
{
|
||||
|
|
|
@ -2051,17 +2051,30 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
|
|||
return caseExpr;
|
||||
}
|
||||
else if (token == BfToken_Dot) // Abbreviated dot syntax ".EnumVal"
|
||||
{
|
||||
// Initializer ".{ x = 1, y = 2 }"
|
||||
{
|
||||
bool handled = false;
|
||||
if (auto nextTokenNode = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
||||
{
|
||||
if (nextTokenNode->mToken == BfToken_This)
|
||||
{
|
||||
auto invocationExpr = CreateObjectCreateExpression(NULL, tokenNode);
|
||||
if (invocationExpr == NULL)
|
||||
return exprLeft;
|
||||
exprLeft = invocationExpr;
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto blockNode = BfNodeDynCast<BfBlock>(mVisitorPos.GetNext()))
|
||||
{
|
||||
// Initializer ".{ x = 1, y = 2 }"
|
||||
auto typeRef = CreateTypeRef(mVisitorPos.GetCurrent());
|
||||
if (typeRef)
|
||||
{
|
||||
exprLeft = TryCreateInitializerExpression(typeRef);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (!handled)
|
||||
{
|
||||
auto memberReferenceExpr = mAlloc->Alloc<BfMemberReferenceExpression>();
|
||||
ReplaceNode(tokenNode, memberReferenceExpr);
|
||||
|
@ -2933,6 +2946,29 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
|
|||
|
||||
BF_ASSERT(tokenNode->GetToken() == token);
|
||||
|
||||
if (token == BfToken_Dot)
|
||||
{
|
||||
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.Get(mVisitorPos.mReadPos + 2)))
|
||||
{
|
||||
if (nextToken->mToken == BfToken_This)
|
||||
{
|
||||
int outNodeIdx = -1;
|
||||
bool isGenericType;
|
||||
bool isTypeRef = ((IsTypeReference(exprLeft, BfToken_This, -1, &outNodeIdx, NULL, &isGenericType)) &&
|
||||
(outNodeIdx != -1));
|
||||
|
||||
if (isTypeRef)
|
||||
{
|
||||
auto invocationExpr = CreateObjectCreateExpression(NULL, exprLeft);
|
||||
if (invocationExpr == NULL)
|
||||
return exprLeft;
|
||||
exprLeft = invocationExpr;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not a binary op, it's a 'close'
|
||||
if (token == BfToken_Bang)
|
||||
{
|
||||
|
@ -4875,6 +4911,11 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
|
|||
}
|
||||
firstNode = qualifiedTypeRef;
|
||||
}
|
||||
else if (auto typeRef = BfNodeDynCast<BfTypeReference>(firstNode))
|
||||
{
|
||||
// Already a typeRef
|
||||
return typeRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isHandled = false;
|
||||
|
@ -5169,6 +5210,15 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
|
|||
BfToken token = tokenNode->GetToken();
|
||||
if (token == BfToken_Dot)
|
||||
{
|
||||
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.Get(mVisitorPos.mReadPos + 2)))
|
||||
{
|
||||
if (nextToken->mToken == BfToken_This)
|
||||
{
|
||||
// Don't encode '.this' in type ref
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BfQualifiedTypeReference* qualifiedTypeRef = mAlloc->Alloc<BfQualifiedTypeReference>();
|
||||
ReplaceNode(typeRef, qualifiedTypeRef);
|
||||
qualifiedTypeRef->mLeft = typeRef;
|
||||
|
@ -5216,6 +5266,15 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
|
|||
{
|
||||
if (tokenNode->GetToken() == BfToken_Dot)
|
||||
{
|
||||
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.Get(mVisitorPos.mReadPos + 2)))
|
||||
{
|
||||
if (nextToken->mToken == BfToken_This)
|
||||
{
|
||||
// Don't encode '.this' in type ref
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BfQualifiedTypeReference* outerQualifiedTypeRef = mAlloc->Alloc<BfQualifiedTypeReference>();
|
||||
ReplaceNode(qualifiedTypeRef, outerQualifiedTypeRef);
|
||||
outerQualifiedTypeRef->mLeft = qualifiedTypeRef;
|
||||
|
@ -5578,6 +5637,11 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
|
|||
{
|
||||
if (auto rightToken = BfNodeDynCast<BfTokenNode>(nextNextToken))
|
||||
{
|
||||
if (rightToken->mToken == BfToken_This)
|
||||
{
|
||||
return leftIdentifier;
|
||||
}
|
||||
|
||||
if (BfTokenIsKeyword(rightToken->mToken))
|
||||
{
|
||||
rightIdentifier = mAlloc->Alloc<BfIdentifierNode>();
|
||||
|
@ -8122,14 +8186,26 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
|||
return allocToken;
|
||||
}
|
||||
|
||||
BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* allocNode)
|
||||
BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* allocNode, BfAstNode* targetNode)
|
||||
{
|
||||
auto objectCreateExpr = mAlloc->Alloc<BfObjectCreateExpression>();
|
||||
BfDeferredAstSizedArray<BfExpression*> arguments(objectCreateExpr->mArguments, mAlloc);
|
||||
BfDeferredAstSizedArray<BfTokenNode*> commas(objectCreateExpr->mCommas, mAlloc);
|
||||
|
||||
ReplaceNode(allocNode, objectCreateExpr);
|
||||
MEMBER_SET(objectCreateExpr, mNewNode, allocNode);
|
||||
BfTypeReference* typeRef = NULL;
|
||||
|
||||
if (allocNode != NULL)
|
||||
{
|
||||
ReplaceNode(allocNode, objectCreateExpr);
|
||||
MEMBER_SET(objectCreateExpr, mNewNode, allocNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplaceNode(targetNode, objectCreateExpr);
|
||||
typeRef = CreateTypeRef(targetNode);
|
||||
if (typeRef == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auto nextNode = mVisitorPos.GetNext();
|
||||
|
||||
|
@ -8145,7 +8221,8 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all
|
|||
// }
|
||||
// }
|
||||
|
||||
auto typeRef = CreateTypeRefAfter(objectCreateExpr);
|
||||
if (typeRef == NULL)
|
||||
typeRef = CreateTypeRefAfter(objectCreateExpr);
|
||||
if (typeRef == NULL)
|
||||
return objectCreateExpr;
|
||||
|
||||
|
@ -8206,6 +8283,42 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all
|
|||
}
|
||||
else
|
||||
{
|
||||
auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||
auto nextNextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.Get(mVisitorPos.mReadPos + 2));
|
||||
if ((nextToken != NULL) && (nextToken->mToken == BfToken_Dot) &&
|
||||
(nextNextToken != NULL) && (nextNextToken->mToken == BfToken_This))
|
||||
{
|
||||
auto ctorExplicitNode = mAlloc->Alloc<BfCtorExplicitNode>();
|
||||
ReplaceNode(nextToken, ctorExplicitNode);
|
||||
ctorExplicitNode->mDotToken = nextToken;
|
||||
MEMBER_SET(ctorExplicitNode, mThisToken, nextNextToken);
|
||||
mVisitorPos.MoveNext();
|
||||
mVisitorPos.MoveNext();
|
||||
MEMBER_SET(objectCreateExpr, mCtorExplicit, ctorExplicitNode);
|
||||
}
|
||||
else if ((nextToken != NULL) && (nextToken->mToken == BfToken_This))
|
||||
{
|
||||
auto ctorExplicitNode = mAlloc->Alloc<BfCtorExplicitNode>();
|
||||
ReplaceNode(nextToken, ctorExplicitNode);
|
||||
ctorExplicitNode->mThisToken = nextToken;
|
||||
mVisitorPos.MoveNext();
|
||||
MEMBER_SET(objectCreateExpr, mCtorExplicit, ctorExplicitNode);
|
||||
}
|
||||
|
||||
if (objectCreateExpr->mCtorExplicit != NULL)
|
||||
{
|
||||
nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||
if ((nextToken->mToken != NULL) && (nextToken->mToken == BfToken_LChevron))
|
||||
{
|
||||
mVisitorPos.MoveNext();
|
||||
auto genericParamsDecl = CreateGenericArguments(nextToken, true);
|
||||
if (genericParamsDecl == NULL)
|
||||
return objectCreateExpr;
|
||||
MEMBER_SET(objectCreateExpr->mCtorExplicit, mGenericArgs, genericParamsDecl);
|
||||
objectCreateExpr->mSrcEnd = objectCreateExpr->mCtorExplicit->mSrcEnd;
|
||||
}
|
||||
}
|
||||
|
||||
// Note- if there WERE an LBracket here then we'd have an 'isArray' case. We pass this in here for
|
||||
// error display purposes
|
||||
tokenNode = ExpectTokenAfter(objectCreateExpr, BfToken_LParen, BfToken_LBracket);
|
||||
|
@ -8308,6 +8421,12 @@ BfMemberReferenceExpression* BfReducer::CreateMemberReferenceExpression(BfAstNod
|
|||
MEMBER_SET(memberReferenceExpr, mMemberName, attrIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
if (tokenNode->GetToken() == BfToken_This)
|
||||
{
|
||||
mVisitorPos.MoveNext();
|
||||
MEMBER_SET(memberReferenceExpr, mMemberName, tokenNode);
|
||||
}
|
||||
}
|
||||
|
||||
if (memberReferenceExpr->mMemberName == NULL)
|
||||
|
|
|
@ -204,7 +204,7 @@ public:
|
|||
BfLambdaBindExpression* CreateLambdaBindExpression(BfAstNode* allocNode, BfTokenNode* parenToken = NULL);
|
||||
BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfBlock* block);
|
||||
BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfTokenNode* openToken);
|
||||
BfObjectCreateExpression* CreateObjectCreateExpression(BfAstNode* allocNode);
|
||||
BfObjectCreateExpression* CreateObjectCreateExpression(BfAstNode* allocNode, BfAstNode* targetNode = NULL);
|
||||
BfScopedInvocationTarget* CreateScopedInvocationTarget(BfAstNode*& targetRef, BfTokenNode* colonToken);
|
||||
BfInvocationExpression* CreateInvocationExpression(BfAstNode* target, CreateExprFlags createExprFlags = CreateExprFlags_None);
|
||||
BfInitializerExpression* TryCreateInitializerExpression(BfAstNode* target);
|
||||
|
|
|
@ -385,7 +385,22 @@ namespace Tests
|
|||
|
||||
public class InnerB
|
||||
{
|
||||
public T mVal;
|
||||
|
||||
public this<T3>(T3 val) where T : operator implicit T3
|
||||
{
|
||||
mVal = (.)val;
|
||||
}
|
||||
}
|
||||
|
||||
public struct InnerC
|
||||
{
|
||||
public T mVal;
|
||||
|
||||
public this<T3>(T3 val) where T : operator implicit T3
|
||||
{
|
||||
mVal = (.)val;
|
||||
}
|
||||
}
|
||||
|
||||
public static OuterA<int,float>.Inner<int16> sVal;
|
||||
|
@ -491,6 +506,13 @@ namespace Tests
|
|||
Test.Assert(specializedType.UnspecializedType == typeof(Dictionary<,>.Enumerator));
|
||||
var t = typeof(Array2<>);
|
||||
t = typeof(ClassH<,>.Inner<>);
|
||||
|
||||
var innerB = new OuterA<int, float>.InnerB.this<int32>(123);
|
||||
Test.Assert(innerB.mVal == 123);
|
||||
delete innerB;
|
||||
|
||||
var innerC = OuterA<int, float>.InnerC.this<int32>(123);
|
||||
Test.Assert(innerC.mVal == 123);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue