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());
|
Visit(propertyMethodDeclaration->ToBase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfStructuralVisitor::Visit(BfPropertyBodyExpression* propertyBodyExpression)
|
||||||
|
{
|
||||||
|
Visit(propertyBodyExpression->ToBase());
|
||||||
|
}
|
||||||
|
|
||||||
void BfStructuralVisitor::Visit(BfPropertyDeclaration* propertyDeclaration)
|
void BfStructuralVisitor::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||||
{
|
{
|
||||||
Visit(propertyDeclaration->ToBase());
|
Visit(propertyDeclaration->ToBase());
|
||||||
|
|
|
@ -322,6 +322,7 @@ class BfQualifiedTypeReference;
|
||||||
class BfUsingDirective;
|
class BfUsingDirective;
|
||||||
class BfUsingStaticDirective;
|
class BfUsingStaticDirective;
|
||||||
class BfPropertyMethodDeclaration;
|
class BfPropertyMethodDeclaration;
|
||||||
|
class BfPropertyBodyExpression;
|
||||||
class BfPropertyDeclaration;
|
class BfPropertyDeclaration;
|
||||||
class BfIndexerDeclaration;
|
class BfIndexerDeclaration;
|
||||||
class BfPreprocesorIgnoredSectionNode;
|
class BfPreprocesorIgnoredSectionNode;
|
||||||
|
@ -500,6 +501,7 @@ public:
|
||||||
virtual void Visit(BfMethodDeclaration* methodDeclaration);
|
virtual void Visit(BfMethodDeclaration* methodDeclaration);
|
||||||
virtual void Visit(BfOperatorDeclaration* operatorDeclaration);
|
virtual void Visit(BfOperatorDeclaration* operatorDeclaration);
|
||||||
virtual void Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration);
|
virtual void Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration);
|
||||||
|
virtual void Visit(BfPropertyBodyExpression* propertyBodyExpression);
|
||||||
virtual void Visit(BfPropertyDeclaration* propertyDeclaration);
|
virtual void Visit(BfPropertyDeclaration* propertyDeclaration);
|
||||||
virtual void Visit(BfIndexerDeclaration* indexerDeclaration);
|
virtual void Visit(BfIndexerDeclaration* indexerDeclaration);
|
||||||
virtual void Visit(BfFieldDeclaration* fieldDeclaration);
|
virtual void Visit(BfFieldDeclaration* fieldDeclaration);
|
||||||
|
@ -2895,11 +2897,18 @@ public:
|
||||||
BfPropertyDeclaration* mPropertyDeclaration;
|
BfPropertyDeclaration* mPropertyDeclaration;
|
||||||
BfAttributeDirective* mAttributes;
|
BfAttributeDirective* mAttributes;
|
||||||
BfTokenNode* mProtectionSpecifier;
|
BfTokenNode* mProtectionSpecifier;
|
||||||
BfTokenNode* mMutSpecifier;
|
BfTokenNode* mMutSpecifier;
|
||||||
BfIdentifierNode* mNameNode;
|
BfIdentifierNode* mNameNode;
|
||||||
BfAstNode* mBody;
|
BfAstNode* mBody;
|
||||||
}; BF_AST_DECL(BfPropertyMethodDeclaration, BfAstNode);
|
}; 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
|
class BfPropertyDeclaration : public BfFieldDeclaration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -2907,8 +2916,8 @@ public:
|
||||||
|
|
||||||
BfTokenNode* mVirtualSpecifier; // either 'virtual', 'override', or 'abstract'
|
BfTokenNode* mVirtualSpecifier; // either 'virtual', 'override', or 'abstract'
|
||||||
BfTypeReference* mExplicitInterface;
|
BfTypeReference* mExplicitInterface;
|
||||||
BfTokenNode* mExplicitInterfaceDotToken;
|
BfTokenNode* mExplicitInterfaceDotToken;
|
||||||
BfBlock* mDefinitionBlock;
|
BfAstNode* mDefinitionBlock;
|
||||||
|
|
||||||
BfSizedArray<BfPropertyMethodDeclaration*> mMethods;
|
BfSizedArray<BfPropertyMethodDeclaration*> mMethods;
|
||||||
|
|
||||||
|
|
|
@ -847,8 +847,10 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String methodName;
|
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();
|
methodName = methodDeclaration->mNameNode->ToString();
|
||||||
|
|
||||||
if (methodName == "get")
|
if (methodName == "get")
|
||||||
|
|
|
@ -1022,6 +1022,13 @@ void BfElementVisitor::Visit(BfPropertyMethodDeclaration* propertyDeclaration)
|
||||||
VisitChild(propertyDeclaration->mBody);
|
VisitChild(propertyDeclaration->mBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfElementVisitor::Visit(BfPropertyBodyExpression* propertyBodyExpression)
|
||||||
|
{
|
||||||
|
Visit(propertyBodyExpression->ToBase());
|
||||||
|
|
||||||
|
VisitChild(propertyBodyExpression->mFatTokenArrow);
|
||||||
|
}
|
||||||
|
|
||||||
void BfElementVisitor::Visit(BfPropertyDeclaration* propertyDeclaration)
|
void BfElementVisitor::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||||
{
|
{
|
||||||
Visit(propertyDeclaration->ToBase());
|
Visit(propertyDeclaration->ToBase());
|
||||||
|
@ -1035,14 +1042,19 @@ void BfElementVisitor::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||||
VisitChild(propertyDeclaration->mExplicitInterface);
|
VisitChild(propertyDeclaration->mExplicitInterface);
|
||||||
VisitChild(propertyDeclaration->mExplicitInterfaceDotToken);
|
VisitChild(propertyDeclaration->mExplicitInterfaceDotToken);
|
||||||
|
|
||||||
if (propertyDeclaration->mDefinitionBlock != NULL)
|
if (auto block = BfNodeDynCast<BfBlock>(propertyDeclaration->mDefinitionBlock))
|
||||||
VisitChild(propertyDeclaration->mDefinitionBlock->mOpenBrace);
|
{
|
||||||
|
VisitChild(block->mOpenBrace);
|
||||||
for (auto& method : propertyDeclaration->mMethods)
|
for (auto& method : propertyDeclaration->mMethods)
|
||||||
VisitChild(method);
|
VisitChild(method);
|
||||||
|
VisitChild(block->mCloseBrace);
|
||||||
if (propertyDeclaration->mDefinitionBlock != NULL)
|
}
|
||||||
VisitChild(propertyDeclaration->mDefinitionBlock->mCloseBrace);
|
else
|
||||||
|
{
|
||||||
|
VisitChild(propertyDeclaration->mDefinitionBlock);
|
||||||
|
for (auto& method : propertyDeclaration->mMethods)
|
||||||
|
VisitChild(method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfElementVisitor::Visit(BfIndexerDeclaration* indexerDeclaration)
|
void BfElementVisitor::Visit(BfIndexerDeclaration* indexerDeclaration)
|
||||||
|
|
|
@ -116,6 +116,7 @@ public:
|
||||||
virtual void Visit(BfMethodDeclaration* methodDeclaration);
|
virtual void Visit(BfMethodDeclaration* methodDeclaration);
|
||||||
virtual void Visit(BfOperatorDeclaration* operatorDeclaration);
|
virtual void Visit(BfOperatorDeclaration* operatorDeclaration);
|
||||||
virtual void Visit(BfPropertyMethodDeclaration* propertyDeclaration);
|
virtual void Visit(BfPropertyMethodDeclaration* propertyDeclaration);
|
||||||
|
virtual void Visit(BfPropertyBodyExpression* propertyBodyExpression);
|
||||||
virtual void Visit(BfPropertyDeclaration* propertyDeclaration);
|
virtual void Visit(BfPropertyDeclaration* propertyDeclaration);
|
||||||
virtual void Visit(BfIndexerDeclaration* indexerDeclaration);
|
virtual void Visit(BfIndexerDeclaration* indexerDeclaration);
|
||||||
virtual void Visit(BfFieldDeclaration* fieldDeclaration);
|
virtual void Visit(BfFieldDeclaration* fieldDeclaration);
|
||||||
|
|
|
@ -16973,9 +16973,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
if (methodDeclaration->mFatArrowToken != NULL)
|
if (methodDeclaration->mFatArrowToken != NULL)
|
||||||
isExpressionBody = true;
|
isExpressionBody = true;
|
||||||
}
|
}
|
||||||
else if (methodDef->GetPropertyDeclaration() != NULL)
|
else if (auto propertyDeclaration = methodDef->GetPropertyDeclaration())
|
||||||
{
|
{
|
||||||
//
|
if (auto propBodyExpr = BfNodeDynCast<BfPropertyBodyExpression>(propertyDeclaration->mDefinitionBlock))
|
||||||
|
{
|
||||||
|
isExpressionBody = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -17011,7 +17014,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
}
|
}
|
||||||
else if (auto expressionBody = BfNodeDynCast<BfExpression>(methodDef->mBody))
|
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);
|
BF_ASSERT(methodDeclaration->mFatArrowToken != NULL);
|
||||||
Fail("Only normal methods can have expression bodies", methodDeclaration->mFatArrowToken);
|
Fail("Only normal methods can have expression bodies", methodDeclaration->mFatArrowToken);
|
||||||
|
@ -19960,8 +19963,13 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
|
||||||
else if (auto methodDeclaration = methodDef->GetMethodDeclaration())
|
else if (auto methodDeclaration = methodDef->GetMethodDeclaration())
|
||||||
overrideToken = methodDeclaration->mVirtualSpecifier;
|
overrideToken = methodDeclaration->mVirtualSpecifier;
|
||||||
if (overrideToken != NULL)
|
if (overrideToken != NULL)
|
||||||
{
|
{
|
||||||
Fail("No suitable method found to override", overrideToken, true);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
return usedMethod;
|
return usedMethod;
|
||||||
|
|
|
@ -2070,17 +2070,25 @@ void BfPrinter::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||||
ExpectSpace();
|
ExpectSpace();
|
||||||
QueueVisitChild(propertyDeclaration->mInitializer);
|
QueueVisitChild(propertyDeclaration->mInitializer);
|
||||||
|
|
||||||
bool doInlineBlock = false;
|
if (auto block = BfNodeDynCast<BfBlock>(propertyDeclaration->mDefinitionBlock))
|
||||||
if (propertyDeclaration->mDefinitionBlock != NULL)
|
|
||||||
DoBlockOpen(propertyDeclaration->mDefinitionBlock, true, &doInlineBlock);
|
|
||||||
|
|
||||||
for (auto method : propertyDeclaration->mMethods)
|
|
||||||
{
|
{
|
||||||
Visit(method);
|
bool doInlineBlock = false;
|
||||||
|
DoBlockOpen(block, true, &doInlineBlock);
|
||||||
|
for (auto method : propertyDeclaration->mMethods)
|
||||||
|
{
|
||||||
|
Visit(method);
|
||||||
|
}
|
||||||
|
DoBlockClose(block, true, doInlineBlock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QueueVisitChild(propertyDeclaration->mDefinitionBlock);
|
||||||
|
ExpectSpace();
|
||||||
|
for (auto method : propertyDeclaration->mMethods)
|
||||||
|
{
|
||||||
|
QueueVisitChild(method->mBody);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propertyDeclaration->mDefinitionBlock != NULL)
|
|
||||||
DoBlockClose(propertyDeclaration->mDefinitionBlock, true, doInlineBlock);
|
|
||||||
|
|
||||||
//QueueVisitChild(propertyDeclaration->mTrailingSemicolon);
|
//QueueVisitChild(propertyDeclaration->mTrailingSemicolon);
|
||||||
|
|
||||||
|
|
|
@ -6606,39 +6606,19 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, int depth)
|
||||||
nextNode = mVisitorPos.Get(blockAfterIdx);
|
nextNode = mVisitorPos.Get(blockAfterIdx);
|
||||||
auto block = BfNodeDynCast<BfBlock>(nextNode);
|
auto block = BfNodeDynCast<BfBlock>(nextNode);
|
||||||
auto tokenNode = BfNodeDynCast<BfTokenNode>(nextNode);
|
auto tokenNode = BfNodeDynCast<BfTokenNode>(nextNode);
|
||||||
|
|
||||||
|
bool isExprBodyProp = (tokenNode != NULL) && (tokenNode->mToken == BfToken_FatArrow);
|
||||||
// Property.
|
// Property.
|
||||||
// If we don't have a token afterwards then still treat it as a property for autocomplete purposes
|
// 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;
|
//mVisitorPos.mReadPos = blockAfterIdx;
|
||||||
|
|
||||||
if (propertyDeclaration == NULL)
|
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>();
|
auto propDecl = mAlloc->Alloc<BfPropertyDeclaration>();
|
||||||
ReplaceNode(typeRef, propDecl);
|
ReplaceNode(typeRef, propDecl);
|
||||||
propDecl->mDocumentation = FindDocumentation(mTypeMemberNodeStart);
|
propDecl->mDocumentation = FindDocumentation(mTypeMemberNodeStart);
|
||||||
|
@ -6684,6 +6664,29 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, int depth)
|
||||||
MEMBER_SET(propertyDeclaration, mDefinitionBlock, block);
|
MEMBER_SET(propertyDeclaration, mDefinitionBlock, block);
|
||||||
ReadPropertyBlock(propertyDeclaration, 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;
|
return propertyDeclaration;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue