mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Added expression bodies for properties
This commit is contained in:
parent
69e3bf94f7
commit
85648cda63
8 changed files with 102 additions and 54 deletions
|
@ -576,6 +576,11 @@ void BfStructuralVisitor::Visit(BfPropertyMethodDeclaration* propertyMethodDecla
|
|||
Visit(propertyMethodDeclaration->ToBase());
|
||||
}
|
||||
|
||||
void BfStructuralVisitor::Visit(BfPropertyBodyExpression* propertyBodyExpression)
|
||||
{
|
||||
Visit(propertyBodyExpression->ToBase());
|
||||
}
|
||||
|
||||
void BfStructuralVisitor::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||
{
|
||||
Visit(propertyDeclaration->ToBase());
|
||||
|
|
|
@ -322,6 +322,7 @@ class BfQualifiedTypeReference;
|
|||
class BfUsingDirective;
|
||||
class BfUsingStaticDirective;
|
||||
class BfPropertyMethodDeclaration;
|
||||
class BfPropertyBodyExpression;
|
||||
class BfPropertyDeclaration;
|
||||
class BfIndexerDeclaration;
|
||||
class BfPreprocesorIgnoredSectionNode;
|
||||
|
@ -500,6 +501,7 @@ public:
|
|||
virtual void Visit(BfMethodDeclaration* methodDeclaration);
|
||||
virtual void Visit(BfOperatorDeclaration* operatorDeclaration);
|
||||
virtual void Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration);
|
||||
virtual void Visit(BfPropertyBodyExpression* propertyBodyExpression);
|
||||
virtual void Visit(BfPropertyDeclaration* propertyDeclaration);
|
||||
virtual void Visit(BfIndexerDeclaration* indexerDeclaration);
|
||||
virtual void Visit(BfFieldDeclaration* fieldDeclaration);
|
||||
|
@ -2900,6 +2902,13 @@ public:
|
|||
BfAstNode* mBody;
|
||||
}; BF_AST_DECL(BfPropertyMethodDeclaration, BfAstNode);
|
||||
|
||||
class BfPropertyBodyExpression : public BfAstNode
|
||||
{
|
||||
public:
|
||||
BF_AST_TYPE(BfPropertyBodyExpression, BfAstNode);
|
||||
BfTokenNode* mFatTokenArrow;
|
||||
}; BF_AST_DECL(BfPropertyBodyExpression, BfAstNode);
|
||||
|
||||
class BfPropertyDeclaration : public BfFieldDeclaration
|
||||
{
|
||||
public:
|
||||
|
@ -2908,7 +2917,7 @@ public:
|
|||
BfTokenNode* mVirtualSpecifier; // either 'virtual', 'override', or 'abstract'
|
||||
BfTypeReference* mExplicitInterface;
|
||||
BfTokenNode* mExplicitInterfaceDotToken;
|
||||
BfBlock* mDefinitionBlock;
|
||||
BfAstNode* mDefinitionBlock;
|
||||
|
||||
BfSizedArray<BfPropertyMethodDeclaration*> mMethods;
|
||||
|
||||
|
|
|
@ -848,7 +848,9 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
|
|||
}
|
||||
|
||||
String methodName;
|
||||
if ((methodDeclaration != NULL) && (methodDeclaration->mNameNode != NULL))
|
||||
if (auto propExprBody = BfNodeDynCast<BfPropertyBodyExpression>(propertyDeclaration->mDefinitionBlock))
|
||||
methodName = "get";
|
||||
else if ((methodDeclaration != NULL) && (methodDeclaration->mNameNode != NULL))
|
||||
methodName = methodDeclaration->mNameNode->ToString();
|
||||
|
||||
if (methodName == "get")
|
||||
|
|
|
@ -1022,6 +1022,13 @@ void BfElementVisitor::Visit(BfPropertyMethodDeclaration* propertyDeclaration)
|
|||
VisitChild(propertyDeclaration->mBody);
|
||||
}
|
||||
|
||||
void BfElementVisitor::Visit(BfPropertyBodyExpression* propertyBodyExpression)
|
||||
{
|
||||
Visit(propertyBodyExpression->ToBase());
|
||||
|
||||
VisitChild(propertyBodyExpression->mFatTokenArrow);
|
||||
}
|
||||
|
||||
void BfElementVisitor::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||
{
|
||||
Visit(propertyDeclaration->ToBase());
|
||||
|
@ -1035,14 +1042,19 @@ void BfElementVisitor::Visit(BfPropertyDeclaration* propertyDeclaration)
|
|||
VisitChild(propertyDeclaration->mExplicitInterface);
|
||||
VisitChild(propertyDeclaration->mExplicitInterfaceDotToken);
|
||||
|
||||
if (propertyDeclaration->mDefinitionBlock != NULL)
|
||||
VisitChild(propertyDeclaration->mDefinitionBlock->mOpenBrace);
|
||||
|
||||
if (auto block = BfNodeDynCast<BfBlock>(propertyDeclaration->mDefinitionBlock))
|
||||
{
|
||||
VisitChild(block->mOpenBrace);
|
||||
for (auto& method : propertyDeclaration->mMethods)
|
||||
VisitChild(method);
|
||||
|
||||
if (propertyDeclaration->mDefinitionBlock != NULL)
|
||||
VisitChild(propertyDeclaration->mDefinitionBlock->mCloseBrace);
|
||||
VisitChild(block->mCloseBrace);
|
||||
}
|
||||
else
|
||||
{
|
||||
VisitChild(propertyDeclaration->mDefinitionBlock);
|
||||
for (auto& method : propertyDeclaration->mMethods)
|
||||
VisitChild(method);
|
||||
}
|
||||
}
|
||||
|
||||
void BfElementVisitor::Visit(BfIndexerDeclaration* indexerDeclaration)
|
||||
|
|
|
@ -116,6 +116,7 @@ public:
|
|||
virtual void Visit(BfMethodDeclaration* methodDeclaration);
|
||||
virtual void Visit(BfOperatorDeclaration* operatorDeclaration);
|
||||
virtual void Visit(BfPropertyMethodDeclaration* propertyDeclaration);
|
||||
virtual void Visit(BfPropertyBodyExpression* propertyBodyExpression);
|
||||
virtual void Visit(BfPropertyDeclaration* propertyDeclaration);
|
||||
virtual void Visit(BfIndexerDeclaration* indexerDeclaration);
|
||||
virtual void Visit(BfFieldDeclaration* fieldDeclaration);
|
||||
|
|
|
@ -16973,9 +16973,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
if (methodDeclaration->mFatArrowToken != NULL)
|
||||
isExpressionBody = true;
|
||||
}
|
||||
else if (methodDef->GetPropertyDeclaration() != NULL)
|
||||
else if (auto propertyDeclaration = methodDef->GetPropertyDeclaration())
|
||||
{
|
||||
//
|
||||
if (auto propBodyExpr = BfNodeDynCast<BfPropertyBodyExpression>(propertyDeclaration->mDefinitionBlock))
|
||||
{
|
||||
isExpressionBody = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -17011,7 +17014,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
}
|
||||
else if (auto expressionBody = BfNodeDynCast<BfExpression>(methodDef->mBody))
|
||||
{
|
||||
if (methodDef->mMethodType != BfMethodType_Normal)
|
||||
if ((methodDef->mMethodType != BfMethodType_Normal) && (propertyDeclaration == NULL))
|
||||
{
|
||||
BF_ASSERT(methodDeclaration->mFatArrowToken != NULL);
|
||||
Fail("Only normal methods can have expression bodies", methodDeclaration->mFatArrowToken);
|
||||
|
@ -19961,6 +19964,11 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
|
|||
overrideToken = methodDeclaration->mVirtualSpecifier;
|
||||
if (overrideToken != NULL)
|
||||
{
|
||||
if ((propertyDeclaration != NULL) && (propertyDeclaration->mNameNode != NULL) &&
|
||||
((methodDef->mMethodType == BfMethodType_PropertyGetter) || (methodDef->mMethodType == BfMethodType_PropertySetter)))
|
||||
Fail(StrFormat("No suitable method found to override for '%s.%s'",
|
||||
propertyDeclaration->mNameNode->ToString().c_str(), (methodDef->mMethodType == BfMethodType_PropertyGetter) ? "get" : "set"), overrideToken, true);
|
||||
else
|
||||
Fail("No suitable method found to override", overrideToken, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -2070,17 +2070,25 @@ void BfPrinter::Visit(BfPropertyDeclaration* propertyDeclaration)
|
|||
ExpectSpace();
|
||||
QueueVisitChild(propertyDeclaration->mInitializer);
|
||||
|
||||
if (auto block = BfNodeDynCast<BfBlock>(propertyDeclaration->mDefinitionBlock))
|
||||
{
|
||||
bool doInlineBlock = false;
|
||||
if (propertyDeclaration->mDefinitionBlock != NULL)
|
||||
DoBlockOpen(propertyDeclaration->mDefinitionBlock, true, &doInlineBlock);
|
||||
|
||||
DoBlockOpen(block, true, &doInlineBlock);
|
||||
for (auto method : propertyDeclaration->mMethods)
|
||||
{
|
||||
Visit(method);
|
||||
}
|
||||
|
||||
if (propertyDeclaration->mDefinitionBlock != NULL)
|
||||
DoBlockClose(propertyDeclaration->mDefinitionBlock, true, doInlineBlock);
|
||||
DoBlockClose(block, true, doInlineBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
QueueVisitChild(propertyDeclaration->mDefinitionBlock);
|
||||
ExpectSpace();
|
||||
for (auto method : propertyDeclaration->mMethods)
|
||||
{
|
||||
QueueVisitChild(method->mBody);
|
||||
}
|
||||
}
|
||||
|
||||
//QueueVisitChild(propertyDeclaration->mTrailingSemicolon);
|
||||
|
||||
|
|
|
@ -6606,39 +6606,19 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, int depth)
|
|||
nextNode = mVisitorPos.Get(blockAfterIdx);
|
||||
auto block = BfNodeDynCast<BfBlock>(nextNode);
|
||||
auto tokenNode = BfNodeDynCast<BfTokenNode>(nextNode);
|
||||
|
||||
bool isExprBodyProp = (tokenNode != NULL) && (tokenNode->mToken == BfToken_FatArrow);
|
||||
// Property.
|
||||
// If we don't have a token afterwards then still treat it as a property for autocomplete purposes
|
||||
if (((block != NULL) || (tokenNode == NULL)) && (typeRef != NULL))
|
||||
if ((typeRef != NULL) &&
|
||||
((block != NULL) || (tokenNode == NULL) || (isExprBodyProp)))
|
||||
{
|
||||
//mVisitorPos.mReadPos = blockAfterIdx;
|
||||
|
||||
if (propertyDeclaration == NULL)
|
||||
{
|
||||
if (block == NULL)
|
||||
if ((block == NULL) && (!isExprBodyProp))
|
||||
{
|
||||
//// Actually treat it as a method
|
||||
//auto methodDecl = mAlloc->Alloc<BfMethodDeclaration>();
|
||||
//ReplaceNode(typeRef, methodDecl);
|
||||
//methodDecl->mDocumentation = FindDocumentation(mTypeMemberNodeStart);
|
||||
//methodDecl->mReturnType = typeRef;
|
||||
|
||||
//if (explicitInterface != NULL)
|
||||
//{
|
||||
// MEMBER_SET(methodDecl, mExplicitInterface, explicitInterface);
|
||||
// MEMBER_SET(methodDecl, mExplicitInterfaceDotToken, explicitInterfaceDot);
|
||||
//}
|
||||
|
||||
//// Don't set the name identifier, this could be bogus
|
||||
////mVisitorPos.mReadPos--;
|
||||
//
|
||||
//// WHY did we want to not set this?
|
||||
//// If we don't, then typing a new method name will end up treating the name node as a typeRef
|
||||
//// which can autocomplete incorrectly
|
||||
//MEMBER_SET(methodDecl, mNameNode, nameIdentifier);
|
||||
|
||||
//return methodDecl;
|
||||
|
||||
|
||||
auto propDecl = mAlloc->Alloc<BfPropertyDeclaration>();
|
||||
ReplaceNode(typeRef, propDecl);
|
||||
propDecl->mDocumentation = FindDocumentation(mTypeMemberNodeStart);
|
||||
|
@ -6684,6 +6664,29 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, int depth)
|
|||
MEMBER_SET(propertyDeclaration, mDefinitionBlock, block);
|
||||
ReadPropertyBlock(propertyDeclaration, block);
|
||||
}
|
||||
else if (isExprBodyProp)
|
||||
{
|
||||
BfDeferredAstSizedArray<BfPropertyMethodDeclaration*> methods(propertyDeclaration->mMethods, mAlloc);
|
||||
|
||||
auto propertyBodyExpr = mAlloc->Alloc<BfPropertyBodyExpression>();
|
||||
ReplaceNode(tokenNode, propertyBodyExpr);
|
||||
MEMBER_SET(propertyBodyExpr, mFatTokenArrow, tokenNode);
|
||||
|
||||
auto method = mAlloc->Alloc<BfPropertyMethodDeclaration>();
|
||||
method->mPropertyDeclaration = propertyDeclaration;
|
||||
method->mNameNode = propertyDeclaration->mNameNode;
|
||||
|
||||
auto expr = CreateExpressionAfter(tokenNode);
|
||||
if (expr != NULL)
|
||||
{
|
||||
MEMBER_SET(method, mBody, expr);
|
||||
propertyDeclaration->SetSrcEnd(expr->GetSrcEnd());
|
||||
}
|
||||
|
||||
methods.Add(method);
|
||||
|
||||
MEMBER_SET(propertyDeclaration, mDefinitionBlock, propertyBodyExpr);
|
||||
}
|
||||
|
||||
return propertyDeclaration;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue