Przeglądaj źródła

Fixed wrappable props and fixed fixed generic binding in MemberRefExpr

Brian Fiete 6 miesięcy temu
rodzic
commit
b1181a936d

+ 56 - 1
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -22236,7 +22236,62 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx
 	if ((isArrowLookup) && (thisValue))
 	if ((isArrowLookup) && (thisValue))
 		thisValue = TryArrowLookup(thisValue, memberRefExpr->mDotToken);
 		thisValue = TryArrowLookup(thisValue, memberRefExpr->mDotToken);
 
 
-	mResult = LookupField(nameRefNode, thisValue, findName);
+	auto nameNode = memberRefExpr->mMemberName;
+
+	if ((thisValue.mType != NULL) && (!thisValue.mType->IsTypeInstance()) && (!thisValue.mType->IsGenericParam()))
+	{
+		if (thisValue.mType->IsSizedArray())
+		{
+			if (thisValue.mType->IsValuelessType())
+			{
+				thisValue.mType = mModule->GetWrappedStructType(thisValue.mType);
+				thisValue.mValue = mModule->mBfIRBuilder->GetFakeVal();
+			}
+			else
+			{
+				thisValue = mModule->MakeAddressable(thisValue);
+				thisValue.mType = mModule->GetWrappedStructType(thisValue.mType);
+				thisValue.mValue = mModule->mBfIRBuilder->CreateBitCast(thisValue.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(thisValue.mType->ToTypeInstance()));
+			}
+		}
+		else if (thisValue.mType->IsPointer())
+		{
+			// Leave alone
+		}
+		else if (thisValue.mType->IsWrappableType())
+		{
+			thisValue.mType = mModule->GetWrappedStructType(thisValue.mType);
+		}		
+	}
+
+	BfTypedValue lookupVal = thisValue;
+	if (thisValue.mType != NULL)
+	{
+		auto lookupType = BindGenericType(nameNode, thisValue.mType);
+		if ((lookupType->IsGenericParam()) && (!thisValue.mType->IsGenericParam()))
+		{
+			bool prevUseMixinGenerics = false;
+			if (mModule->mCurMethodState->mMixinState != NULL)
+			{
+				prevUseMixinGenerics = mModule->mCurMethodState->mMixinState->mUseMixinGenerics;
+				mModule->mCurMethodState->mMixinState->mUseMixinGenerics = true;
+			}
+
+			// Try to lookup from generic binding
+			mResult = LookupField(nameRight, BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), lookupType), findName, BfLookupFieldFlag_BindOnly);
+
+			if (mModule->mCurMethodState->mMixinState != NULL)
+				mModule->mCurMethodState->mMixinState->mUseMixinGenerics = prevUseMixinGenerics;
+
+			if (mPropDef != NULL)
+			{
+				mOrigPropTarget = lookupVal;
+				return;
+			}
+		}
+	}
+
+	mResult = LookupField(nameRefNode, lookupVal, findName);
 
 
 	if ((!mResult) && (mPropDef == NULL))
 	if ((!mResult) && (mPropDef == NULL))
 	{
 	{

+ 24 - 0
IDEHelper/Tests/src/Interfaces.bf

@@ -432,6 +432,29 @@ namespace Tests
             T sum = a + b;
             T sum = a + b;
         }
         }
 
 
+		interface IIntVal
+		{
+			int IntVal { get; }
+		}
+
+		struct StructC : IIntVal
+		{
+			int IIntVal.IntVal
+			{
+				get
+				{
+					return 123;
+				}
+			}
+		}
+
+		static int GetIntVals<T>(T val) where T : IIntVal
+		{
+			int a = (val).[Friend]IntVal;
+			int b = val.IntVal;
+			return a + b;
+		}
+
 		[Test]
 		[Test]
 		public static void TestDefaults()
 		public static void TestDefaults()
 		{
 		{
@@ -473,6 +496,7 @@ namespace Tests
 			Test.Assert(TestIFaceD2(cg) == 999);
 			Test.Assert(TestIFaceD2(cg) == 999);
 
 
 			ClassH ch = scope .();
 			ClassH ch = scope .();
+			Test.Assert(GetIntVals(StructC()) == 246);
 		}
 		}
 	}
 	}
 }
 }