1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Enhanced expression-body support

This commit is contained in:
Brian Fiete 2020-05-08 11:11:01 -07:00
parent a94d76ac5d
commit 6af96d8f6d
5 changed files with 91 additions and 46 deletions

View file

@ -2574,7 +2574,7 @@ public:
BfTokenNode* mCloseParen; BfTokenNode* mCloseParen;
BfSizedArray<ASTREF(BfIdentifierNode*)> mParams; BfSizedArray<ASTREF(BfIdentifierNode*)> mParams;
BfSizedArray<ASTREF(BfTokenNode*)> mCommas; BfSizedArray<ASTREF(BfTokenNode*)> mCommas;
BfTokenNode* mFatArrowToken; BfTokenNode* mFatArrowToken;
BfAstNode* mBody; // Either expression or block BfAstNode* mBody; // Either expression or block
BfFieldDtorDeclaration* mDtor; BfFieldDtorDeclaration* mDtor;
}; BF_AST_DECL(BfLambdaBindExpression, BfExpression); }; BF_AST_DECL(BfLambdaBindExpression, BfExpression);
@ -2827,7 +2827,7 @@ public:
ASTREF(BfGenericConstraintsDeclaration*) mGenericConstraintsDeclaration; ASTREF(BfGenericConstraintsDeclaration*) mGenericConstraintsDeclaration;
ASTREF(BfAstNode*) mEndSemicolon; ASTREF(BfAstNode*) mEndSemicolon;
ASTREF(BfTokenNode*) mFatArrowToken; ASTREF(BfTokenNode*) mFatArrowToken;
ASTREF(BfAstNode*) mBody; // Either expression or block ASTREF(BfAstNode*) mBody; // Either expression or block
//BfMethodDef* mMethodDef; //BfMethodDef* mMethodDef;
@ -2916,7 +2916,9 @@ public:
BfTokenNode* mProtectionSpecifier; BfTokenNode* mProtectionSpecifier;
BfTokenNode* mMutSpecifier; BfTokenNode* mMutSpecifier;
BfIdentifierNode* mNameNode; BfIdentifierNode* mNameNode;
BfTokenNode* mFatArrowToken;
BfAstNode* mBody; BfAstNode* mBody;
BfAstNode* mEndSemicolon;
}; BF_AST_DECL(BfPropertyMethodDeclaration, BfAstNode); }; BF_AST_DECL(BfPropertyMethodDeclaration, BfAstNode);
class BfPropertyBodyExpression : public BfAstNode class BfPropertyBodyExpression : public BfAstNode

View file

@ -1012,7 +1012,9 @@ void BfElementVisitor::Visit(BfPropertyMethodDeclaration* propertyDeclaration)
VisitChild(propertyDeclaration->mProtectionSpecifier); VisitChild(propertyDeclaration->mProtectionSpecifier);
VisitChild(propertyDeclaration->mNameNode); VisitChild(propertyDeclaration->mNameNode);
VisitChild(propertyDeclaration->mMutSpecifier); VisitChild(propertyDeclaration->mMutSpecifier);
VisitChild(propertyDeclaration->mFatArrowToken);
VisitChild(propertyDeclaration->mBody); VisitChild(propertyDeclaration->mBody);
VisitChild(propertyDeclaration->mEndSemicolon);
} }
void BfElementVisitor::Visit(BfPropertyBodyExpression* propertyBodyExpression) void BfElementVisitor::Visit(BfPropertyBodyExpression* propertyBodyExpression)

View file

@ -13447,7 +13447,7 @@ BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArr
auto methodDecl = methodDef->GetMethodDeclaration(); auto methodDecl = methodDef->GetMethodDeclaration();
auto methodDeclBlock = BfNodeDynCast<BfBlock>(methodDecl->mBody); auto methodDeclBlock = BfNodeDynCast<BfBlock>(methodDecl->mBody);
if (methodDeclBlock == NULL) if (methodDeclBlock == NULL)
return BfTypedValue(); return GetDefaultTypedValue(GetPrimitiveType(BfTypeCode_IntPtr)); // Must not have an append alloc at all!
BfTypedValue constValue; BfTypedValue constValue;
@ -17596,7 +17596,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
isExpressionBody = true; isExpressionBody = true;
} }
else if (auto propertyDeclaration = methodDef->GetPropertyDeclaration()) else if (auto propertyDeclaration = methodDef->GetPropertyDeclaration())
{ {
auto propertyMethodDeclaration = methodDef->GetPropertyMethodDeclaration();
if ((propertyMethodDeclaration != NULL) && (propertyMethodDeclaration->mFatArrowToken != NULL))
isExpressionBody = true;
if (auto propBodyExpr = BfNodeDynCast<BfPropertyBodyExpression>(propertyDeclaration->mDefinitionBlock)) if (auto propBodyExpr = BfNodeDynCast<BfPropertyBodyExpression>(propertyDeclaration->mDefinitionBlock))
{ {
isExpressionBody = true; isExpressionBody = true;
@ -17636,42 +17639,45 @@ 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) && (propertyDeclaration == NULL)) // 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);
} // }
auto expectingType = mCurMethodInstance->mReturnType; auto expectingType = mCurMethodInstance->mReturnType;
// What was this error for?
// if ((expectingType->IsVoid()) && (IsInSpecializedSection())) // if ((expectingType->IsVoid()) && (IsInSpecializedSection()))
// { // {
// Warn(0, "Using a 'void' return with an expression-bodied method isn't needed. Consider removing '=>' token", methodDeclaration->mFatArrowToken); // Warn(0, "Using a 'void' return with an expression-bodied method isn't needed. Consider removing '=>' token", methodDeclaration->mFatArrowToken);
// } // }
//TODO: Why did we have all this stuff for handling void? BfEvalExprFlags exprEvalFlags = BfEvalExprFlags_None;
// if (expectingType->IsVoid()) if (expectingType->IsVoid())
// { {
// bool wasReturnGenericParam = false; exprEvalFlags = BfEvalExprFlags_NoCast;
// if ((mCurMethodState->mClosureState != NULL) && (mCurMethodState->mClosureState->mReturnType != NULL))
// { bool wasReturnGenericParam = false;
// wasReturnGenericParam = mCurMethodState->mClosureState->mReturnType->IsGenericParam(); if ((mCurMethodState->mClosureState != NULL) && (mCurMethodState->mClosureState->mReturnType != NULL))
// } {
// else wasReturnGenericParam = mCurMethodState->mClosureState->mReturnType->IsGenericParam();
// { }
// auto unspecializedMethodInstance = GetUnspecializedMethodInstance(mCurMethodInstance); else
// if ((unspecializedMethodInstance != NULL) && (unspecializedMethodInstance->mReturnType->IsGenericParam())) {
// wasReturnGenericParam = true; auto unspecializedMethodInstance = GetUnspecializedMethodInstance(mCurMethodInstance);
// } if ((unspecializedMethodInstance != NULL) && (unspecializedMethodInstance->mReturnType->IsGenericParam()))
// wasReturnGenericParam = true;
// // If we the void return was from a generic specialization, allow us to return a void result, }
// // otherwise treat expression as though it must be a statement
// bool isStatement = expressionBody->VerifyIsStatement(mCompiler->mPassInstance, wasReturnGenericParam); // If we the void return was from a generic specialization, allow us to return a void result,
// if (isStatement) // otherwise treat expression as though it must be a statement
// expectingType = NULL; bool isStatement = expressionBody->VerifyIsStatement(mCompiler->mPassInstance, wasReturnGenericParam);
// } if (isStatement)
expectingType = NULL;
}
UpdateSrcPos(expressionBody); UpdateSrcPos(expressionBody);
auto retVal = CreateValueFromExpression(expressionBody, expectingType); auto retVal = CreateValueFromExpression(expressionBody, expectingType, exprEvalFlags);
if ((retVal) && (expectingType != NULL)) if ((retVal) && (expectingType != NULL))
{ {
mCurMethodState->mHadReturn = true; mCurMethodState->mHadReturn = true;
@ -20881,7 +20887,13 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
{ {
auto propertyMethodDecl = methodDef->GetPropertyMethodDeclaration(); auto propertyMethodDecl = methodDef->GetPropertyMethodDeclaration();
Fail(StrFormat("Property '%s' %s accessor not defined in interface '%s'", propertyDecl->mNameNode->ToString().c_str(), String name;
if (auto indexerDeclaration = BfNodeDynCast<BfIndexerDeclaration>(propertyDecl))
name = "this[]";
else if (propertyDecl->mNameNode != NULL)
propertyDecl->mNameNode->ToString(name);
Fail(StrFormat("Property '%s' %s accessor not defined in interface '%s'", name.c_str(),
(methodDef->mMethodType == BfMethodType_PropertyGetter) ? "get" : "set", TypeToString(ifaceInst).c_str()), methodDef->GetRefNode(), true); (methodDef->mMethodType == BfMethodType_PropertyGetter) ? "get" : "set", TypeToString(ifaceInst).c_str()), methodDef->GetRefNode(), true);
} }
else else

View file

@ -2349,9 +2349,12 @@ void BfPrinter::Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration)
ExpectSpace(); ExpectSpace();
QueueVisitChild(propertyMethodDeclaration->mMutSpecifier); QueueVisitChild(propertyMethodDeclaration->mMutSpecifier);
ExpectSpace(); ExpectSpace();
QueueVisitChild(propertyMethodDeclaration->mFatArrowToken);
ExpectSpace();
if (auto block = BfNodeDynCast<BfBlock>(propertyMethodDeclaration->mBody)) if (auto block = BfNodeDynCast<BfBlock>(propertyMethodDeclaration->mBody))
ExpectNewLine(); ExpectNewLine();
QueueVisitChild(propertyMethodDeclaration->mBody); QueueVisitChild(propertyMethodDeclaration->mBody);
QueueVisitChild(propertyMethodDeclaration->mEndSemicolon);
} }
void BfPrinter::Visit(BfPropertyDeclaration* propertyDeclaration) void BfPrinter::Visit(BfPropertyDeclaration* propertyDeclaration)

View file

@ -6157,17 +6157,36 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf
bodyAfterNode = tokenNode; bodyAfterNode = tokenNode;
mVisitorPos.MoveNext(); mVisitorPos.MoveNext();
child = mVisitorPos.GetCurrent(); child = mVisitorPos.GetNext();
} }
auto endSemicolon = BfNodeDynCast<BfTokenNode>(child); bool handled = false;
if ((endSemicolon != NULL) && (endSemicolon->GetToken() == BfToken_Semicolon)) BfTokenNode* fatArrowToken = NULL;
BfAstNode* endSemicolon = NULL;
if (tokenNode = BfNodeDynCast<BfTokenNode>(child))
{ {
body = endSemicolon; if ((tokenNode->GetToken() == BfToken_Semicolon))
mVisitorPos.MoveNext(); {
} handled = true;
endSemicolon = tokenNode;
mVisitorPos.MoveNext();
}
else if (tokenNode->mToken == BfToken_FatArrow)
{
handled = true;
fatArrowToken = tokenNode;
mVisitorPos.MoveNext();
if (body == NULL) auto expr = CreateExpressionAfter(tokenNode);
if (expr != NULL)
{
body = expr;
endSemicolon = ExpectTokenAfter(expr, BfToken_Semicolon);
}
}
}
if (!handled)
{ {
if (bodyAfterNode != NULL) if (bodyAfterNode != NULL)
{ {
@ -6175,8 +6194,12 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf
} }
else else
{ {
auto accessorBlock = BfNodeDynCast<BfBlock>(child); if (auto accessorBlock = BfNodeDynCast<BfBlock>(child))
if (accessorBlock == NULL) {
body = accessorBlock;
mVisitorPos.MoveNext();
}
if (body == NULL)
{ {
if (child != NULL) if (child != NULL)
{ {
@ -6185,9 +6208,7 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf
mVisitorPos.MoveNext(); mVisitorPos.MoveNext();
} }
continue; continue;
} }
body = accessorBlock;
mVisitorPos.MoveNext();
} }
} }
@ -6200,7 +6221,7 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf
} }
} }
if (body == NULL) if ((body == NULL) && (!handled))
{ {
if (protectionSpecifier != NULL) if (protectionSpecifier != NULL)
AddErrorNode(protectionSpecifier); AddErrorNode(protectionSpecifier);
@ -6213,6 +6234,11 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf
auto method = mAlloc->Alloc<BfPropertyMethodDeclaration>(); auto method = mAlloc->Alloc<BfPropertyMethodDeclaration>();
method->mPropertyDeclaration = propertyDeclaration; method->mPropertyDeclaration = propertyDeclaration;
if (fatArrowToken != NULL)
MEMBER_SET(method, mFatArrowToken, fatArrowToken);
if (endSemicolon != NULL)
MEMBER_SET(method, mEndSemicolon, endSemicolon);
if (protectionSpecifier != NULL) if (protectionSpecifier != NULL)
MEMBER_SET(method, mProtectionSpecifier, protectionSpecifier); MEMBER_SET(method, mProtectionSpecifier, protectionSpecifier);
if (accessorIdentifier != NULL) if (accessorIdentifier != NULL)