浏览代码

Allow ref property setter specifier

Brian Fiete 3 年之前
父节点
当前提交
40b0d78d16

+ 1 - 0
IDEHelper/Compiler/BfAst.h

@@ -3099,6 +3099,7 @@ public:
 	BfPropertyDeclaration* mPropertyDeclaration;
 	BfAttributeDirective* mAttributes;
 	BfAstNode* mProtectionSpecifier;
+	BfTokenNode* mSetRefSpecifier;
 	BfTokenNode* mMutSpecifier;	
 	BfIdentifierNode* mNameNode;
 	BfTokenNode* mFatArrowToken;

+ 11 - 4
IDEHelper/Compiler/BfDefBuilder.cpp

@@ -1078,12 +1078,19 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
 			if (BfNodeDynCast<BfTokenNode>(methodDeclaration->mBody) != NULL)
 				methodDef->mIsMutating = true; // Don't require "set mut;", just "set;"
 			
-			auto paramDef = new BfParameterDef();					
+			auto paramDef = new BfParameterDef();
 			paramDef->mName = "value";
-			if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(propertyDeclaration->mTypeRef))		
-			 	paramDef->mTypeRef = refTypeRef->mElementType;		
+			paramDef->mTypeRef = propertyDeclaration->mTypeRef;
+			if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(propertyDeclaration->mTypeRef))
+			{
+				if (methodDeclaration->mSetRefSpecifier == NULL)
+					paramDef->mTypeRef = refTypeRef->mElementType;
+			}
 			else
-			 	paramDef->mTypeRef = propertyDeclaration->mTypeRef;
+			{
+				if (methodDeclaration->mSetRefSpecifier != NULL)
+					Fail("Property setter 'ref' can only be used with a 'ref' property type", methodDeclaration->mSetRefSpecifier);
+			}
 			methodDef->mParams.Insert(0, paramDef);					
 			propertyDef->mMethods.Add(methodDef);
 		}

+ 2 - 1
IDEHelper/Compiler/BfElementVisitor.cpp

@@ -1050,8 +1050,9 @@ void BfElementVisitor::Visit(BfPropertyMethodDeclaration* propertyDeclaration)
 	VisitChild(propertyDeclaration->mAttributes);
 	VisitChild(propertyDeclaration->mProtectionSpecifier);
 	VisitChild(propertyDeclaration->mNameNode);
+	VisitChild(propertyDeclaration->mSetRefSpecifier);
 	VisitChild(propertyDeclaration->mMutSpecifier);
-	VisitChild(propertyDeclaration->mFatArrowToken);	
+	VisitChild(propertyDeclaration->mFatArrowToken);
 	VisitChild(propertyDeclaration->mBody);
 	VisitChild(propertyDeclaration->mEndSemicolon);
 }

+ 4 - 1
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -18128,7 +18128,10 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool
 						mModule->AssertErrorState();
 						return;
 					}
-					convVal = mModule->CreateValueFromExpression(assignExpr->mRight, wantType, (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_PendingPropSet));
+					BfEvalExprFlags exprFlags = (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_PendingPropSet);
+					if (wantType->IsRef())
+						exprFlags = (BfEvalExprFlags)(exprFlags | BfEvalExprFlags_AllowRefExpr);
+					convVal = mModule->CreateValueFromExpression(assignExpr->mRight, wantType, exprFlags);
 				}
 				if (!convVal)
 				{

+ 2 - 0
IDEHelper/Compiler/BfPrinter.cpp

@@ -2545,6 +2545,8 @@ void BfPrinter::Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration)
 	ExpectSpace();		
 	QueueVisitChild(propertyMethodDeclaration->mNameNode);
 	ExpectSpace();
+	QueueVisitChild(propertyMethodDeclaration->mSetRefSpecifier);
+	ExpectSpace();
 	QueueVisitChild(propertyMethodDeclaration->mMutSpecifier);
 	ExpectSpace();
 	QueueVisitChild(propertyMethodDeclaration->mFatArrowToken);

+ 18 - 3
IDEHelper/Compiler/BfReducer.cpp

@@ -6392,6 +6392,7 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf
 
 		String accessorName;
 		BfTokenNode* mutSpecifier = NULL;
+		BfTokenNode* refSpecifier = NULL;
 
 		while (true)
 		{
@@ -6459,8 +6460,18 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf
 		BfAstNode* bodyAfterNode = accessorIdentifier;
 
 		BfAstNode* body = NULL;
-
+		
 		auto tokenNode = BfNodeDynCast<BfTokenNode>(child);
+		if ((tokenNode != NULL) && (tokenNode->GetToken() == BfToken_Ref) && (accessorName == "set"))
+		{			
+			refSpecifier = tokenNode;
+			bodyAfterNode = tokenNode;
+
+			mVisitorPos.MoveNext();
+			child = mVisitorPos.GetNext();
+			tokenNode = BfNodeDynCast<BfTokenNode>(child);
+		}
+
 		if ((tokenNode != NULL) && (tokenNode->GetToken() == BfToken_Mut))
 		{
 			if (mutSpecifier != NULL)
@@ -6472,8 +6483,8 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf
 
 			mVisitorPos.MoveNext();
 			child = mVisitorPos.GetNext();
-		}
-
+		}		
+		
 		bool handled = false;
 		BfTokenNode* fatArrowToken = NULL;
 		BfAstNode* endSemicolon = NULL;
@@ -6543,6 +6554,8 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf
 				AddErrorNode(accessorIdentifier);
 			if (mutSpecifier != NULL)
 				AddErrorNode(mutSpecifier);
+			if (refSpecifier != NULL)
+				AddErrorNode(refSpecifier);
 			continue;
 		}
 
@@ -6561,6 +6574,8 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf
 		{
 			MEMBER_SET(method, mBody, body);
 		}
+		if (refSpecifier != NULL)
+			MEMBER_SET(method, mSetRefSpecifier, refSpecifier);
 		if (mutSpecifier != NULL)
 			MEMBER_SET(method, mMutSpecifier, mutSpecifier);
 		// 		if ((accessorBlock != NULL) && (IsNodeRelevant(propertyDeclaration)))