mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Generic constructors
This commit is contained in:
parent
64d646e130
commit
04ea8a6634
13 changed files with 267 additions and 37 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue