mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +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());
|
Visit(genericArgumentsNode->ToBase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfStructuralVisitor::Visit(BfCtorExplicitNode* ctorExplicitNode)
|
||||||
|
{
|
||||||
|
Visit(ctorExplicitNode->ToBase());
|
||||||
|
}
|
||||||
|
|
||||||
void BfStructuralVisitor::Visit(BfStatement* stmt)
|
void BfStructuralVisitor::Visit(BfStatement* stmt)
|
||||||
{
|
{
|
||||||
Visit(stmt->ToBase());
|
Visit(stmt->ToBase());
|
||||||
|
|
|
@ -337,6 +337,7 @@ class BfScopeNode;
|
||||||
class BfNewNode;
|
class BfNewNode;
|
||||||
class BfLabeledBlock;
|
class BfLabeledBlock;
|
||||||
class BfGenericArgumentsNode;
|
class BfGenericArgumentsNode;
|
||||||
|
class BfCtorExplicitNode;
|
||||||
class BfStatement;
|
class BfStatement;
|
||||||
class BfLabelableStatement;
|
class BfLabelableStatement;
|
||||||
class BfExpression;
|
class BfExpression;
|
||||||
|
@ -529,6 +530,7 @@ public:
|
||||||
virtual void Visit(BfGenericOperatorConstraint* genericConstraints);
|
virtual void Visit(BfGenericOperatorConstraint* genericConstraints);
|
||||||
virtual void Visit(BfGenericConstraintsDeclaration* genericConstraints);
|
virtual void Visit(BfGenericConstraintsDeclaration* genericConstraints);
|
||||||
virtual void Visit(BfGenericArgumentsNode* genericArgumentsNode);
|
virtual void Visit(BfGenericArgumentsNode* genericArgumentsNode);
|
||||||
|
virtual void Visit(BfCtorExplicitNode* genericArgumentsNode);
|
||||||
|
|
||||||
virtual void Visit(BfEmptyStatement* emptyStmt);
|
virtual void Visit(BfEmptyStatement* emptyStmt);
|
||||||
virtual void Visit(BfTokenNode* tokenNode);
|
virtual void Visit(BfTokenNode* tokenNode);
|
||||||
|
@ -2911,6 +2913,16 @@ public:
|
||||||
BfAstNode* mStatement;
|
BfAstNode* mStatement;
|
||||||
}; BF_AST_DECL(BfAttributedStatement, BfStatement);
|
}; 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
|
class BfObjectCreateExpression : public BfMethodBoundExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -2919,6 +2931,7 @@ public:
|
||||||
BfAstNode* mNewNode;
|
BfAstNode* mNewNode;
|
||||||
BfTokenNode* mStarToken;
|
BfTokenNode* mStarToken;
|
||||||
BfTypeReference* mTypeRef;
|
BfTypeReference* mTypeRef;
|
||||||
|
BfCtorExplicitNode* mCtorExplicit;
|
||||||
BfTokenNode* mOpenToken;
|
BfTokenNode* mOpenToken;
|
||||||
BfTokenNode* mCloseToken;
|
BfTokenNode* mCloseToken;
|
||||||
BfSizedArray<BfExpression*> mArguments;
|
BfSizedArray<BfExpression*> mArguments;
|
||||||
|
|
|
@ -604,7 +604,8 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
|
||||||
if ((methodDef->mMethodType == BfMethodType_Normal) ||
|
if ((methodDef->mMethodType == BfMethodType_Normal) ||
|
||||||
(methodDef->mMethodType == BfMethodType_Operator) ||
|
(methodDef->mMethodType == BfMethodType_Operator) ||
|
||||||
(methodDef->mMethodType == BfMethodType_Mixin) ||
|
(methodDef->mMethodType == BfMethodType_Mixin) ||
|
||||||
(methodDef->mMethodType == BfMethodType_Extension))
|
(methodDef->mMethodType == BfMethodType_Extension) ||
|
||||||
|
(methodDef->mMethodType == BfMethodType_Ctor))
|
||||||
{
|
{
|
||||||
bool isGeneric = (methodDeclaration->mGenericParams != NULL) || (!mCurTypeDef->mGenericParamDefs.IsEmpty());
|
bool isGeneric = (methodDeclaration->mGenericParams != NULL) || (!mCurTypeDef->mGenericParamDefs.IsEmpty());
|
||||||
ParseGenericParams(methodDeclaration->mGenericParams, methodDeclaration->mGenericConstraintsDeclaration, methodDef->mGenericParams, &methodDef->mExternalConstraints, outerGenericSize, isGeneric);
|
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);
|
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'
|
// Insert a 'appendIdx'
|
||||||
BfParameterDef* newParam = new BfParameterDef();
|
BfParameterDef* newParam = new BfParameterDef();
|
||||||
newParam->mName = "appendIdx";
|
newParam->mName = "appendIdx";
|
||||||
|
|
|
@ -114,6 +114,15 @@ void BfElementVisitor::Visit(BfGenericArgumentsNode* genericArgumentsNode)
|
||||||
VisitChild(genericArgumentsNode->mCloseChevron);
|
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)
|
void BfElementVisitor::Visit(BfStatement* stmt)
|
||||||
{
|
{
|
||||||
Visit(stmt->ToBase());
|
Visit(stmt->ToBase());
|
||||||
|
@ -627,6 +636,7 @@ void BfElementVisitor::Visit(BfObjectCreateExpression* newExpr)
|
||||||
VisitChild(newExpr->mNewNode);
|
VisitChild(newExpr->mNewNode);
|
||||||
VisitChild(newExpr->mStarToken);
|
VisitChild(newExpr->mStarToken);
|
||||||
VisitChild(newExpr->mTypeRef);
|
VisitChild(newExpr->mTypeRef);
|
||||||
|
VisitChild(newExpr->mCtorExplicit);
|
||||||
VisitChild(newExpr->mOpenToken);
|
VisitChild(newExpr->mOpenToken);
|
||||||
VisitChild(newExpr->mCloseToken);
|
VisitChild(newExpr->mCloseToken);
|
||||||
for (auto& val : newExpr->mArguments)
|
for (auto& val : newExpr->mArguments)
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
virtual void Visit(BfGenericOperatorConstraint* genericConstraints);
|
virtual void Visit(BfGenericOperatorConstraint* genericConstraints);
|
||||||
virtual void Visit(BfGenericConstraintsDeclaration* genericConstraints);
|
virtual void Visit(BfGenericConstraintsDeclaration* genericConstraints);
|
||||||
virtual void Visit(BfGenericArgumentsNode* genericArgumentsNode);
|
virtual void Visit(BfGenericArgumentsNode* genericArgumentsNode);
|
||||||
|
virtual void Visit(BfCtorExplicitNode* genericArgumentsNode);
|
||||||
|
|
||||||
virtual void Visit(BfEmptyStatement* emptyStmt);
|
virtual void Visit(BfEmptyStatement* emptyStmt);
|
||||||
virtual void Visit(BfTokenNode* tokenNode);
|
virtual void Visit(BfTokenNode* tokenNode);
|
||||||
|
|
|
@ -7977,7 +7977,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
arrayType, false);
|
arrayType, false);
|
||||||
|
|
||||||
BfResolvedArgs resolvedArgs;
|
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
|
//TODO: Assert 'length' var is at slot 1
|
||||||
auto arrayBits = mModule->mBfIRBuilder->CreateBitCast(expandedParamsArray.mValue, mModule->mBfIRBuilder->MapType(arrayType->mBaseType));
|
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;
|
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
|
// Temporarily disable so we don't capture calls in params
|
||||||
SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
|
SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
|
||||||
|
@ -8750,7 +8751,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
||||||
static int sCtorCount = 0;
|
static int sCtorCount = 0;
|
||||||
sCtorCount++;
|
sCtorCount++;
|
||||||
|
|
||||||
BfMethodMatcher methodMatcher(targetSrc, mModule, "", argValues.mResolvedArgs, BfMethodGenericArguments());
|
BfMethodMatcher methodMatcher(targetSrc, mModule, "", argValues.mResolvedArgs, methodGenericArguments);
|
||||||
methodMatcher.mBfEvalExprFlags = mBfEvalExprFlags;
|
methodMatcher.mBfEvalExprFlags = mBfEvalExprFlags;
|
||||||
|
|
||||||
BfTypeVector typeGenericArguments;
|
BfTypeVector typeGenericArguments;
|
||||||
|
@ -8842,11 +8843,13 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
||||||
// There should always be a constructor
|
// There should always be a constructor
|
||||||
BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
|
BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
|
||||||
|
|
||||||
auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher.mBestMethodGenericArguments);
|
//auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher.mBestMethodGenericArguments);
|
||||||
if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc))
|
|
||||||
{
|
auto moduleMethodInstance = GetSelectedMethod(methodMatcher);
|
||||||
|
if (!moduleMethodInstance)
|
||||||
|
return BfTypedValue();
|
||||||
|
if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc))
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
}
|
|
||||||
|
|
||||||
BfAutoComplete* autoComplete = GetAutoComplete();
|
BfAutoComplete* autoComplete = GetAutoComplete();
|
||||||
if (autoComplete != NULL)
|
if (autoComplete != NULL)
|
||||||
|
@ -10142,7 +10145,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
mResultLocalVar = NULL;
|
mResultLocalVar = NULL;
|
||||||
mResultFieldInstance = NULL;
|
mResultFieldInstance = NULL;
|
||||||
mResultLocalVarRefNode = 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()))
|
if ((result) && (!result.mType->IsVoid()))
|
||||||
return result;
|
return result;
|
||||||
mModule->ValidateAllocation(resolvedTypeInstance, targetSrc);
|
mModule->ValidateAllocation(resolvedTypeInstance, targetSrc);
|
||||||
|
@ -14042,7 +14045,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
||||||
}
|
}
|
||||||
|
|
||||||
BfResolvedArgs resolvedArgs;
|
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 baseDelegateType = VerifyBaseDelegateType(delegateTypeInstance->mBaseType);
|
||||||
auto baseDelegate = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(baseDelegateType, BfIRPopulateType_Full));
|
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);
|
CheckObjectCreateTypeRef(mExpectingType, allocNode);
|
||||||
|
|
||||||
BfAttributeState attributeState;
|
BfAttributeState attributeState;
|
||||||
|
@ -15499,12 +15506,18 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
BfAllocTarget allocTarget;
|
BfAllocTarget allocTarget;
|
||||||
ResolveAllocTarget(allocTarget, allocNode, newToken, &attributeState.mCustomAttributes);
|
ResolveAllocTarget(allocTarget, allocNode, newToken, &attributeState.mCustomAttributes);
|
||||||
|
|
||||||
bool isScopeAlloc = newToken->GetToken() == BfToken_Scope;
|
bool isStructAlloc = newToken == NULL;
|
||||||
bool isAppendAlloc = newToken->GetToken() == BfToken_Append;
|
bool isScopeAlloc = (newToken != NULL) && (newToken->GetToken() == BfToken_Scope);
|
||||||
bool isStackAlloc = (newToken->GetToken() == BfToken_Stack) || (isScopeAlloc);
|
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 isArrayAlloc = false;// (objCreateExpr->mArraySizeSpecifier != NULL);
|
||||||
bool isRawArrayAlloc = (objCreateExpr != NULL) && (objCreateExpr->mStarToken != 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 (isScopeAlloc)
|
||||||
{
|
{
|
||||||
if ((mBfEvalExprFlags & BfEvalExprFlags_FieldInitializer) != 0)
|
if ((mBfEvalExprFlags & BfEvalExprFlags_FieldInitializer) != 0)
|
||||||
|
@ -15579,6 +15592,10 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
{
|
{
|
||||||
unresolvedTypeRef = mExpectingType->GetUnderlyingType();
|
unresolvedTypeRef = mExpectingType->GetUnderlyingType();
|
||||||
}
|
}
|
||||||
|
else if (mExpectingType->IsStruct())
|
||||||
|
{
|
||||||
|
unresolvedTypeRef = mExpectingType;
|
||||||
|
}
|
||||||
else if (mExpectingType->IsVar())
|
else if (mExpectingType->IsVar())
|
||||||
unresolvedTypeRef = mExpectingType;
|
unresolvedTypeRef = mExpectingType;
|
||||||
}
|
}
|
||||||
|
@ -16114,11 +16131,11 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
if (rawAutoComplete != NULL)
|
if (rawAutoComplete != NULL)
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<bool> prevCapturing(rawAutoComplete->mIsCapturingMethodMatchInfo, false);
|
SetAndRestoreValue<bool> prevCapturing(rawAutoComplete->mIsCapturingMethodMatchInfo, false);
|
||||||
MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, false);
|
MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, methodGenericArguments, false);
|
||||||
}
|
}
|
||||||
else
|
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
|
//TODO: Assert 'length' var is at slot 1
|
||||||
|
@ -16294,7 +16311,11 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
{
|
{
|
||||||
auto wasCapturingMethodInfo = autoComplete->mIsCapturingMethodMatchInfo;
|
auto wasCapturingMethodInfo = autoComplete->mIsCapturingMethodMatchInfo;
|
||||||
autoComplete->CheckInvocation(objCreateExpr, objCreateExpr->mOpenToken, objCreateExpr->mCloseToken, objCreateExpr->mCommas);
|
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 ((wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo))
|
||||||
{
|
{
|
||||||
if (autoComplete->mMethodMatchInfo != NULL)
|
if (autoComplete->mMethodMatchInfo != NULL)
|
||||||
|
@ -16308,7 +16329,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
auto refNode = allocNode;
|
auto refNode = allocNode;
|
||||||
if (objCreateExpr != NULL)
|
if (objCreateExpr != NULL)
|
||||||
refNode = objCreateExpr->mTypeRef;
|
refNode = objCreateExpr->mTypeRef;
|
||||||
MatchConstructor(refNode, objCreateExpr, emtpyThis, typeInstance, argValues, false, true);
|
MatchConstructor(refNode, objCreateExpr, emtpyThis, typeInstance, argValues, false, methodGenericArguments, true);
|
||||||
}
|
}
|
||||||
if (objCreateExpr != NULL)
|
if (objCreateExpr != NULL)
|
||||||
mModule->ValidateAllocation(typeInstance, objCreateExpr->mTypeRef);
|
mModule->ValidateAllocation(typeInstance, objCreateExpr->mTypeRef);
|
||||||
|
@ -16329,7 +16350,16 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
}
|
}
|
||||||
else
|
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;
|
SizedArray<BfIRValue, 2> irArgs;
|
||||||
if (bindResult.mIRArgs.size() > 1)
|
if (bindResult.mIRArgs.size() > 1)
|
||||||
|
@ -16523,6 +16553,17 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
{
|
{
|
||||||
mModule->mCompiler->mCeMachine->ClearAppendAllocInfo();
|
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)
|
void BfExprEvaluator::Visit(BfBoxExpression* boxExpr)
|
||||||
|
@ -16612,7 +16653,13 @@ void BfExprEvaluator::ResolveAllocTarget(BfAllocTarget& allocTarget, BfAstNode*
|
||||||
|
|
||||||
allocTarget.mRefNode = allocNode;
|
allocTarget.mRefNode = allocNode;
|
||||||
newToken = BfNodeDynCast<BfTokenNode>(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))
|
if (auto scopeNode = BfNodeDynCast<BfScopeNode>(allocNode))
|
||||||
{
|
{
|
||||||
|
@ -18269,7 +18316,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
else
|
else
|
||||||
mResult = BfTypedValue(mModule->CreateAlloca(expectingType), expectingType, BfTypedValueKind_TempAddr);
|
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()))
|
if ((ctorResult) && (!ctorResult.mType->IsVoid()))
|
||||||
mResult = ctorResult;
|
mResult = ctorResult;
|
||||||
mModule->ValidateAllocation(expectingType, invocationExpr->mTarget);
|
mModule->ValidateAllocation(expectingType, invocationExpr->mTarget);
|
||||||
|
@ -23591,7 +23638,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
|
||||||
ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
||||||
|
|
||||||
mResult = BfTypedValue(alloca, allocType, true);
|
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()))
|
if ((result) && (!result.mType->IsVoid()))
|
||||||
mResult = result;
|
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 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);
|
void PushThis(BfAstNode* targetSrc, BfTypedValue callTarget, BfMethodInstance* methodInstance, SizedArrayImpl<BfIRValue>& irArgs, bool skipMutCheck = false);
|
||||||
BfTypedValue MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType,
|
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 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, const BfMethodGenericArguments& methodGenericArguments, BfCheckedKind checkedKind = BfCheckedKind_NotSet);
|
BfResolvedArgs& argValue, const BfMethodGenericArguments& methodGenericArguments, BfCheckedKind checkedKind = BfCheckedKind_NotSet);
|
||||||
|
|
|
@ -778,7 +778,7 @@ public:
|
||||||
if (typeInst != NULL)
|
if (typeInst != NULL)
|
||||||
{
|
{
|
||||||
exprEvaluator.ResolveArgValues(argValues);
|
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;
|
exprEvaluator.mFunctionBindResult = NULL;
|
||||||
|
|
||||||
|
@ -4765,7 +4765,7 @@ void BfModule::AppendedObjectInit(BfFieldInstance* fieldInst)
|
||||||
mBfIRBuilder->CreateStore(GetConstValue8(BfObjectFlag_AppendAlloc), thisFlagsPtr);
|
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)
|
void BfModule::CheckInterfaceMethod(BfMethodInstance* methodInstance)
|
||||||
|
@ -17149,7 +17149,7 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
|
||||||
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
|
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
|
||||||
exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
||||||
SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(exprEvaluator.mFunctionBindResult, &bindResult);
|
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)
|
if (bindResult.mMethodInstance == NULL)
|
||||||
|
@ -17196,7 +17196,7 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
|
||||||
bindResult.mSkipThis = true;
|
bindResult.mSkipThis = true;
|
||||||
bindResult.mWantsArgs = true;
|
bindResult.mWantsArgs = true;
|
||||||
SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(exprEvaluator.mFunctionBindResult, &bindResult);
|
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());
|
BF_ASSERT(bindResult.mIRArgs[0].IsFake());
|
||||||
bindResult.mIRArgs.RemoveAt(0);
|
bindResult.mIRArgs.RemoveAt(0);
|
||||||
calcAppendArgs = bindResult.mIRArgs;
|
calcAppendArgs = bindResult.mIRArgs;
|
||||||
|
@ -18704,7 +18704,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
appendIdxVal = BfTypedValue(localVar->mValue, intRefType);
|
appendIdxVal = BfTypedValue(localVar->mValue, intRefType);
|
||||||
mCurMethodState->mCurAppendAlign = 1; // Don't make any assumptions about how the base leaves the alignment
|
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)
|
if (autoComplete != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5537,7 +5537,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
BfTypedValue emptyThis(mBfIRBuilder->GetFakeVal(), resolvedTypeRef, resolvedTypeRef->IsStruct());
|
BfTypedValue emptyThis(mBfIRBuilder->GetFakeVal(), resolvedTypeRef, resolvedTypeRef->IsStruct());
|
||||||
|
|
||||||
exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_Comptime;
|
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))
|
if ((bindResult.mMethodInstance != NULL) && (bindResult.mMethodInstance->mMethodDef->mHasAppend))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1913,6 +1913,7 @@ void BfPrinter::Visit(BfObjectCreateExpression* newExpr)
|
||||||
ExpectSpace();
|
ExpectSpace();
|
||||||
|
|
||||||
VisitChild(newExpr->mTypeRef);
|
VisitChild(newExpr->mTypeRef);
|
||||||
|
VisitChild(newExpr->mCtorExplicit);
|
||||||
|
|
||||||
if (newExpr->mStarToken != NULL)
|
if (newExpr->mStarToken != NULL)
|
||||||
{
|
{
|
||||||
|
@ -2497,6 +2498,7 @@ void BfPrinter::Visit(BfConstructorDeclaration* ctorDeclaration)
|
||||||
{
|
{
|
||||||
QueueVisitChild(ctorDeclaration->mThisToken);
|
QueueVisitChild(ctorDeclaration->mThisToken);
|
||||||
}
|
}
|
||||||
|
QueueVisitChild(ctorDeclaration->mGenericParams);
|
||||||
|
|
||||||
QueueVisitChild(ctorDeclaration->mOpenParen);
|
QueueVisitChild(ctorDeclaration->mOpenParen);
|
||||||
for (int i = 0; i < (int) ctorDeclaration->mParams.size(); i++)
|
for (int i = 0; i < (int) ctorDeclaration->mParams.size(); i++)
|
||||||
|
@ -2513,6 +2515,8 @@ void BfPrinter::Visit(BfConstructorDeclaration* ctorDeclaration)
|
||||||
QueueVisitChild(ctorDeclaration->mInitializerColonToken);
|
QueueVisitChild(ctorDeclaration->mInitializerColonToken);
|
||||||
ExpectSpace();
|
ExpectSpace();
|
||||||
QueueVisitChild(ctorDeclaration->mInitializer);
|
QueueVisitChild(ctorDeclaration->mInitializer);
|
||||||
|
ExpectSpace();
|
||||||
|
QueueVisitChild(ctorDeclaration->mGenericConstraintsDeclaration);
|
||||||
|
|
||||||
if (ctorDeclaration->mFatArrowToken != NULL)
|
if (ctorDeclaration->mFatArrowToken != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2052,16 +2052,29 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
|
||||||
}
|
}
|
||||||
else if (token == BfToken_Dot) // Abbreviated dot syntax ".EnumVal"
|
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()))
|
if (auto blockNode = BfNodeDynCast<BfBlock>(mVisitorPos.GetNext()))
|
||||||
{
|
{
|
||||||
|
// Initializer ".{ x = 1, y = 2 }"
|
||||||
auto typeRef = CreateTypeRef(mVisitorPos.GetCurrent());
|
auto typeRef = CreateTypeRef(mVisitorPos.GetCurrent());
|
||||||
if (typeRef)
|
if (typeRef)
|
||||||
{
|
{
|
||||||
exprLeft = TryCreateInitializerExpression(typeRef);
|
exprLeft = TryCreateInitializerExpression(typeRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (!handled)
|
||||||
{
|
{
|
||||||
auto memberReferenceExpr = mAlloc->Alloc<BfMemberReferenceExpression>();
|
auto memberReferenceExpr = mAlloc->Alloc<BfMemberReferenceExpression>();
|
||||||
ReplaceNode(tokenNode, memberReferenceExpr);
|
ReplaceNode(tokenNode, memberReferenceExpr);
|
||||||
|
@ -2933,6 +2946,29 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
|
||||||
|
|
||||||
BF_ASSERT(tokenNode->GetToken() == token);
|
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'
|
// Not a binary op, it's a 'close'
|
||||||
if (token == BfToken_Bang)
|
if (token == BfToken_Bang)
|
||||||
{
|
{
|
||||||
|
@ -4875,6 +4911,11 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
|
||||||
}
|
}
|
||||||
firstNode = qualifiedTypeRef;
|
firstNode = qualifiedTypeRef;
|
||||||
}
|
}
|
||||||
|
else if (auto typeRef = BfNodeDynCast<BfTypeReference>(firstNode))
|
||||||
|
{
|
||||||
|
// Already a typeRef
|
||||||
|
return typeRef;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool isHandled = false;
|
bool isHandled = false;
|
||||||
|
@ -5169,6 +5210,15 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
|
||||||
BfToken token = tokenNode->GetToken();
|
BfToken token = tokenNode->GetToken();
|
||||||
if (token == BfToken_Dot)
|
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>();
|
BfQualifiedTypeReference* qualifiedTypeRef = mAlloc->Alloc<BfQualifiedTypeReference>();
|
||||||
ReplaceNode(typeRef, qualifiedTypeRef);
|
ReplaceNode(typeRef, qualifiedTypeRef);
|
||||||
qualifiedTypeRef->mLeft = typeRef;
|
qualifiedTypeRef->mLeft = typeRef;
|
||||||
|
@ -5216,6 +5266,15 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
|
||||||
{
|
{
|
||||||
if (tokenNode->GetToken() == BfToken_Dot)
|
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>();
|
BfQualifiedTypeReference* outerQualifiedTypeRef = mAlloc->Alloc<BfQualifiedTypeReference>();
|
||||||
ReplaceNode(qualifiedTypeRef, outerQualifiedTypeRef);
|
ReplaceNode(qualifiedTypeRef, outerQualifiedTypeRef);
|
||||||
outerQualifiedTypeRef->mLeft = qualifiedTypeRef;
|
outerQualifiedTypeRef->mLeft = qualifiedTypeRef;
|
||||||
|
@ -5578,6 +5637,11 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
|
||||||
{
|
{
|
||||||
if (auto rightToken = BfNodeDynCast<BfTokenNode>(nextNextToken))
|
if (auto rightToken = BfNodeDynCast<BfTokenNode>(nextNextToken))
|
||||||
{
|
{
|
||||||
|
if (rightToken->mToken == BfToken_This)
|
||||||
|
{
|
||||||
|
return leftIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
if (BfTokenIsKeyword(rightToken->mToken))
|
if (BfTokenIsKeyword(rightToken->mToken))
|
||||||
{
|
{
|
||||||
rightIdentifier = mAlloc->Alloc<BfIdentifierNode>();
|
rightIdentifier = mAlloc->Alloc<BfIdentifierNode>();
|
||||||
|
@ -8122,14 +8186,26 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
||||||
return allocToken;
|
return allocToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* allocNode)
|
BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* allocNode, BfAstNode* targetNode)
|
||||||
{
|
{
|
||||||
auto objectCreateExpr = mAlloc->Alloc<BfObjectCreateExpression>();
|
auto objectCreateExpr = mAlloc->Alloc<BfObjectCreateExpression>();
|
||||||
BfDeferredAstSizedArray<BfExpression*> arguments(objectCreateExpr->mArguments, mAlloc);
|
BfDeferredAstSizedArray<BfExpression*> arguments(objectCreateExpr->mArguments, mAlloc);
|
||||||
BfDeferredAstSizedArray<BfTokenNode*> commas(objectCreateExpr->mCommas, mAlloc);
|
BfDeferredAstSizedArray<BfTokenNode*> commas(objectCreateExpr->mCommas, mAlloc);
|
||||||
|
|
||||||
|
BfTypeReference* typeRef = NULL;
|
||||||
|
|
||||||
|
if (allocNode != NULL)
|
||||||
|
{
|
||||||
ReplaceNode(allocNode, objectCreateExpr);
|
ReplaceNode(allocNode, objectCreateExpr);
|
||||||
MEMBER_SET(objectCreateExpr, mNewNode, allocNode);
|
MEMBER_SET(objectCreateExpr, mNewNode, allocNode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReplaceNode(targetNode, objectCreateExpr);
|
||||||
|
typeRef = CreateTypeRef(targetNode);
|
||||||
|
if (typeRef == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
auto nextNode = mVisitorPos.GetNext();
|
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)
|
if (typeRef == NULL)
|
||||||
return objectCreateExpr;
|
return objectCreateExpr;
|
||||||
|
|
||||||
|
@ -8206,6 +8283,42 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all
|
||||||
}
|
}
|
||||||
else
|
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
|
// Note- if there WERE an LBracket here then we'd have an 'isArray' case. We pass this in here for
|
||||||
// error display purposes
|
// error display purposes
|
||||||
tokenNode = ExpectTokenAfter(objectCreateExpr, BfToken_LParen, BfToken_LBracket);
|
tokenNode = ExpectTokenAfter(objectCreateExpr, BfToken_LParen, BfToken_LBracket);
|
||||||
|
@ -8308,6 +8421,12 @@ BfMemberReferenceExpression* BfReducer::CreateMemberReferenceExpression(BfAstNod
|
||||||
MEMBER_SET(memberReferenceExpr, mMemberName, attrIdentifier);
|
MEMBER_SET(memberReferenceExpr, mMemberName, attrIdentifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tokenNode->GetToken() == BfToken_This)
|
||||||
|
{
|
||||||
|
mVisitorPos.MoveNext();
|
||||||
|
MEMBER_SET(memberReferenceExpr, mMemberName, tokenNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memberReferenceExpr->mMemberName == NULL)
|
if (memberReferenceExpr->mMemberName == NULL)
|
||||||
|
|
|
@ -204,7 +204,7 @@ public:
|
||||||
BfLambdaBindExpression* CreateLambdaBindExpression(BfAstNode* allocNode, BfTokenNode* parenToken = NULL);
|
BfLambdaBindExpression* CreateLambdaBindExpression(BfAstNode* allocNode, BfTokenNode* parenToken = NULL);
|
||||||
BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfBlock* block);
|
BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfBlock* block);
|
||||||
BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfTokenNode* openToken);
|
BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfTokenNode* openToken);
|
||||||
BfObjectCreateExpression* CreateObjectCreateExpression(BfAstNode* allocNode);
|
BfObjectCreateExpression* CreateObjectCreateExpression(BfAstNode* allocNode, BfAstNode* targetNode = NULL);
|
||||||
BfScopedInvocationTarget* CreateScopedInvocationTarget(BfAstNode*& targetRef, BfTokenNode* colonToken);
|
BfScopedInvocationTarget* CreateScopedInvocationTarget(BfAstNode*& targetRef, BfTokenNode* colonToken);
|
||||||
BfInvocationExpression* CreateInvocationExpression(BfAstNode* target, CreateExprFlags createExprFlags = CreateExprFlags_None);
|
BfInvocationExpression* CreateInvocationExpression(BfAstNode* target, CreateExprFlags createExprFlags = CreateExprFlags_None);
|
||||||
BfInitializerExpression* TryCreateInitializerExpression(BfAstNode* target);
|
BfInitializerExpression* TryCreateInitializerExpression(BfAstNode* target);
|
||||||
|
|
|
@ -385,7 +385,22 @@ namespace Tests
|
||||||
|
|
||||||
public class InnerB
|
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;
|
public static OuterA<int,float>.Inner<int16> sVal;
|
||||||
|
@ -491,6 +506,13 @@ namespace Tests
|
||||||
Test.Assert(specializedType.UnspecializedType == typeof(Dictionary<,>.Enumerator));
|
Test.Assert(specializedType.UnspecializedType == typeof(Dictionary<,>.Enumerator));
|
||||||
var t = typeof(Array2<>);
|
var t = typeof(Array2<>);
|
||||||
t = typeof(ClassH<,>.Inner<>);
|
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