Browse Source

Added @return support

Brian Fiete 4 years ago
parent
commit
e06949dac1

+ 1 - 1
BeefLibs/corlib/src/Reflection/CEMethodInfo.bf

@@ -49,7 +49,7 @@ namespace System.Reflection
 			get
 			{
 				if (Compiler.IsComptime)
-					Type.[Friend]GetType((.)Type.[Friend]Comptime_Method_GetInfo(mNativeMethodInstance).mReturnTypeId);
+					return Type.[Friend]GetType((.)Type.[Friend]Comptime_Method_GetInfo(mNativeMethodInstance).mReturnTypeId);
 				return null;
 			}
 		}

+ 2 - 2
BeefLibs/corlib/src/Type.bf

@@ -583,7 +583,7 @@ namespace System
 		{
 			if (Compiler.IsComptime)
 			{
-				return Comptime_Type_GetCustomAttribute((int32)TypeId, typeof(T).TypeId, null);
+				return Comptime_Type_GetCustomAttribute((int32)TypeId, (.)typeof(T).TypeId, null);
 			}
 
 			if (var typeInstance = this as TypeInstance)
@@ -596,7 +596,7 @@ namespace System
 			if (Compiler.IsComptime)
 			{
 				T val = ?;
-				if (Comptime_Type_GetCustomAttribute((int32)TypeId, typeof(T).TypeId, &val))
+				if (Comptime_Type_GetCustomAttribute((int32)TypeId, (.)typeof(T).TypeId, &val))
 					return val;
 				return .Err;
 			}

+ 2 - 0
IDEHelper/Compiler/BfCompiler.cpp

@@ -426,6 +426,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
 	mOrderedAttributeTypeDef = NULL;
 	mPointerTTypeDef = NULL;
 	mPointerTypeDef = NULL;
+	mReflectTypeIdTypeDef = NULL;
 	mReflectArrayType = NULL;
 	mReflectFieldDataDef = NULL;
 	mReflectFieldSplatDataDef = NULL;
@@ -6650,6 +6651,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
 	mOrderedAttributeTypeDef = _GetRequiredType("System.OrderedAttribute");
 	mPointerTTypeDef = _GetRequiredType("System.Pointer", 1);
 	mPointerTypeDef = _GetRequiredType("System.Pointer", 0);
+	mReflectTypeIdTypeDef = _GetRequiredType("System.Reflection.TypeId");
 	mReflectArrayType = _GetRequiredType("System.Reflection.ArrayType");
 	mReflectFieldDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldData");
 	mReflectFieldSplatDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldSplatData");

+ 3 - 2
IDEHelper/Compiler/BfCompiler.h

@@ -374,9 +374,10 @@ public:
 	
 	BfTypeDef* mMethodRefTypeDef;
 	BfTypeDef* mNullableTypeDef;
-	
+		
 	BfTypeDef* mPointerTTypeDef;
 	BfTypeDef* mPointerTypeDef;
+	BfTypeDef* mReflectTypeIdTypeDef;
 	BfTypeDef* mReflectArrayType;
 	BfTypeDef* mReflectFieldDataDef;
 	BfTypeDef* mReflectFieldSplatDataDef;
@@ -388,7 +389,7 @@ public:
 	BfTypeDef* mReflectSizedArrayType;
 	BfTypeDef* mReflectSpecializedGenericType;
 	BfTypeDef* mReflectTypeInstanceTypeDef;
-	BfTypeDef* mReflectUnspecializedGenericType;	
+	BfTypeDef* mReflectUnspecializedGenericType;		
 	
 	BfTypeDef* mSizedArrayTypeDef;
 	BfTypeDef* mAttributeTypeDef;

+ 5 - 1
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -3727,7 +3727,8 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
 				wantName = findName;
 				while (wantName.StartsWith("@"))
 				{
-					varSkipCount++;
+					if (wantName != "@return")
+						varSkipCount++;
 					wantName.Remove(0);
 				}
 			}
@@ -9942,7 +9943,10 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
 	else if (memberName == "IsSizedArray")
 		_BoolResult(type->IsSizedArray());
 	else if (memberName == "TypeId")
+	{
 		_Int32Result(type->mTypeId);
+		mResult.mType = mModule->ResolveTypeDef(mModule->mCompiler->mReflectTypeIdTypeDef);
+	}
 	else if (memberName == "GenericParamCount")
 	{
 		auto genericTypeInst = type->ToGenericTypeInstance();

+ 32 - 5
IDEHelper/Compiler/BfModule.cpp

@@ -2236,6 +2236,28 @@ void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit)
 	}
 }
 
+void BfModule::CreateRetValLocal()
+{
+	if (mCurMethodState->mRetVal)
+	{
+		BfLocalVariable* localDef = new BfLocalVariable();
+		localDef->mName = "return";
+		localDef->mResolvedType = mCurMethodState->mRetVal.mType;
+		localDef->mAddr = mCurMethodState->mRetVal.mValue;
+		localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional;				
+		AddLocalVariableDef(localDef);
+	}
+	else if (mCurMethodState->mRetValAddr)
+	{
+		BfLocalVariable* localDef = new BfLocalVariable();
+		localDef->mName = "return";
+		localDef->mResolvedType = CreateRefType(mCurMethodInstance->mReturnType);
+		localDef->mAddr = mCurMethodState->mRetValAddr;
+		localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional;
+		AddLocalVariableDef(localDef);
+	}
+}
+
 void BfModule::MarkDynStack(BfScopeData* scopeData)
 {
 	auto checkScope = mCurMethodState->mCurScope;
@@ -5316,8 +5338,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 		else
 			typeDataVar = mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(mContext->mBfTypeType));
 				
-		mTypeDataRefs[typeInstance] = typeDataVar;
-
+		mTypeDataRefs[type] = typeDataVar;
 		return typeDataVar;
 	}
 	
@@ -6876,7 +6897,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 	}
 	typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType));
 
-	mTypeDataRefs[typeInstance] = typeDataVar;
+	mTypeDataRefs[typeInstance] = typeDataVar;	
 
 	if ((!mIsComptimeModule) && (classVDataVar))
 	{	
@@ -13972,7 +13993,7 @@ void BfModule::CreateDIRetVal()
 		}
 
 		mCurMethodState->mDIRetVal = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope,
-			"__return", mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, mBfIRBuilder->DbgGetType(dbgType));
+			"@return", mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, mBfIRBuilder->DbgGetType(dbgType));
 		auto declareCall = mBfIRBuilder->DbgInsertDeclare(dbgValue, mCurMethodState->mDIRetVal);
 	}	
 }
@@ -14292,6 +14313,9 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa
 			{
 				if (deferredCallEntry->mDeferredBlock != NULL)
 				{
+					if (checkScope == &mCurMethodState->mHeadScope)
+						CreateRetValLocal();
+
 					SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, deferredCallEntry->mEmitRefNode);
 					VisitEmbeddedStatement(deferredCallEntry->mDeferredBlock, NULL, BfEmbeddedStatementFlags_IsDeferredBlock);
 				}
@@ -14374,12 +14398,15 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa
 		if (hasWork)
 		{
 			SetAndRestoreValue<BfScopeData*> prevScope(mCurMethodState->mCurScope, checkScope);
-
+			
 			if (deferCloseNode != NULL)
 			{							
 				UpdateSrcPos(deferCloseNode);
 			}
 
+			if (checkScope == &mCurMethodState->mHeadScope)
+				CreateRetValLocal();
+
 			if (doneBlock)
 			{
 				bool crossingMixin = mCurMethodState->mCurScope->mMixinDepth != checkScope->mMixinDepth;				

+ 1 - 0
IDEHelper/Compiler/BfModule.h

@@ -1776,6 +1776,7 @@ public:
 	BfLocalVariable* AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo = false, bool doAliasValue = false, BfIRValue declareBefore = BfIRValue(), BfIRInitType initType = BfIRInitType_NotSet);	
 	bool TryLocalVariableInit(BfLocalVariable* localVar);
 	void LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit);
+	void CreateRetValLocal();
 	void CreateDIRetVal();
 	BfTypedValue CreateTuple(const Array<BfTypedValue>& values, const Array<String>& fieldNames);
 	void CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType);

+ 3 - 2
IDEHelper/Compiler/BfReducer.cpp

@@ -9768,11 +9768,12 @@ void BfReducer::HandleBlock(BfBlock* block, bool allowEndingExpression)
 			flags = (CreateStmtFlags)(flags | CreateStmtFlags_AllowUnterminatedExpression);
 
 		auto statement = CreateStatement(node, flags);
-		if (statement == NULL)
+		if ((statement == NULL) && (mSource != NULL))
 			statement = mSource->CreateErrorNode(node);
 
 		isDone = !mVisitorPos.MoveNext();
-		mVisitorPos.Write(statement);
+		if (statement != NULL)
+			mVisitorPos.Write(statement);
 	}
 
 	mVisitorPos.Trim();

+ 15 - 14
IDEHelper/Compiler/CeMachine.cpp

@@ -2861,11 +2861,11 @@ addr_ce CeContext::GetReflectType(int typeId)
 		ceModule->PopulateType(bfType, BfPopulateType_DataAndMethods);
 
 	Dictionary<int, int> usedStringMap;
-	auto irData = ceModule->CreateTypeData(bfType, usedStringMap, true, true, true, false);	
+	auto irData = ceModule->CreateTypeData(bfType, usedStringMap, true, true, true, false);		
 	
 	BeValue* beValue = NULL;
 	if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData))
-	{		
+	{
 		if (constant->mConstType == BfConstType_BitCast)
 		{
 			auto bitcast = (BfConstantBitCast*)constant;
@@ -2875,12 +2875,13 @@ addr_ce CeContext::GetReflectType(int typeId)
 		{
 			auto globalVar = (BfGlobalVar*)constant;
 			beValue = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen->GetBeValue(globalVar->mStreamId);
-		}		
+		}
 	}
-		
-	if (auto constant = BeValueDynCast<BeConstant>(beValue))	
+
+	if (auto constant = BeValueDynCast<BeConstant>(beValue))
 		*addrPtr = GetConstantData(constant);
 
+	// We need to 'get' again because we might have resized	
 	return *addrPtr;
 }
 
@@ -4103,9 +4104,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
 			{
 				int32 size = *(int32*)((uint8*)stackPtr + 4);
 				CE_CHECKALLOC(size);
-				uint8* ptr = CeMalloc(size);
-				addr_ce& result = *(addr_ce*)((uint8*)stackPtr + 0);
-				result = (addr_ce)(ptr - memStart);
+				uint8* ptr = CeMalloc(size);				
+				CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize);
 				handled = true;
 				return true;
 			}
@@ -4185,7 +4185,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
 
 				auto reflectType = GetReflectType(typeId);
 				_FixVariables();
-				*(addr_ce*)(stackPtr + 0) = reflectType;
+				CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
 				handled = true;
 				return true;
 			}
@@ -4194,7 +4194,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
 				int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
 				auto reflectType = GetReflectType(typeId);
 				_FixVariables();
-				*(addr_ce*)(stackPtr + 0) = reflectType;
+				CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);				
 				handled = true;
 				return true;
 			}
@@ -4209,7 +4209,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
 				}
 				auto reflectType = GetReflectType(typeName);
 				_FixVariables();
-				*(addr_ce*)(stackPtr + 0) = reflectType;
+				CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
 				handled = true;
 				return true;
 			}
@@ -4220,7 +4220,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
 
 				auto reflectType = GetReflectSpecializedType(typeAddr, typeSpan);
 				_FixVariables();
-				*(addr_ce*)(stackPtr + 0) = reflectType;
+				CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
 				handled = true;
 				return true;
 			}
@@ -4348,10 +4348,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
 					return false;
 				}
 				
+				addr_ce stringAddr = GetString(methodInstance->GetParamName(paramIdx));
+				_FixVariables();
 				*(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId;
 				*(int16*)(stackPtr + 4) = 0; // Flags
-				CeSetAddrVal(stackPtr + 4+2, GetString(methodInstance->GetParamName(paramIdx)), ptrSize);
-				_FixVariables();
+				CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize);				
 				handled = true;
 				return true;
 			}

+ 24 - 5
IDEHelper/Tests/src/Comptime.bf

@@ -48,8 +48,20 @@ namespace Tests
 				String emit = scope $"LogAttribute.gLog.AppendF($\"Called {method}";
 				for (var fieldIdx < method.ParamCount)
 					emit.AppendF($" {{ {method.GetParamName(fieldIdx)} }}");
-				emit.Append("\");");
+				emit.Append("\\n\");");
 				Compiler.EmitMethodEntry(method, emit);
+
+				if (var genericType = method.ReturnType as SpecializedGenericType)
+				{
+					if ((genericType.UnspecializedType == typeof(Result<>)) || (genericType.UnspecializedType == typeof(Result<,>)))
+					{
+						Compiler.EmitMethodExit(method, """
+							if (@return case .Err)
+							LogAttribute.gLog.AppendF($"Error: {@return}");
+							""");
+					}
+					
+				}
 			}
 		}
 
@@ -68,10 +80,16 @@ namespace Tests
 			}
 		}
 
-		[Log]
-		public static void MethodA(int a, int b)
+		enum MethodAErr
 		{
+			ErrorA,
+			ErrorB
+		}
 
+		[Log]
+		static Result<int, MethodAErr> MethodA(int a, int b)
+		{
+			return .Err(.ErrorB);
 		}
 
 		static Type GetBiggerType(Type t)
@@ -104,8 +122,9 @@ namespace Tests
 			Compiler.Mixin("int val = 99;");
 			Test.Assert(val == 99);
 
-			MethodA(34, 45);
-			Debug.Assert(LogAttribute.gLog == "Called Tests.Comptime.MethodA(int a, int b) 34 45");
+
+			MethodA(34, 45).IgnoreError();
+			Debug.Assert(LogAttribute.gLog == "Called Tests.Comptime.MethodA(int a, int b) 34 45\nError: Err(ErrorB)");
 
 			var v0 = GetBigger((int8)123);
 			Test.Assert(v0.GetType() == typeof(int16));