Переглянути джерело

Fix indexing generic params

Brian Fiete 10 місяців тому
батько
коміт
c53ef1c346
2 змінених файлів з 47 додано та 10 видалено
  1. 16 10
      IDEHelper/Compiler/BfExprEvaluator.cpp
  2. 31 0
      IDEHelper/Tests/src/Indexers.bf

+ 16 - 10
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -21943,9 +21943,13 @@ void BfExprEvaluator::HandleIndexerExpression(BfIndexerExpression* indexerExpr,
 		mResult = BfTypedValue(mModule->GetDefaultValue(target.mType), target.mType, true);
 		return;
 	}
-
-	if (target.mType->IsTypeInstance())
+	
+	if ((target.mType->IsTypeInstance()) || (target.mType->IsGenericParam()))
 	{
+		BfGenericParamInstance* genericParamInstance = NULL;
+		if (target.mType->IsGenericParam())
+			genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)target.mType);
+
 		mIndexerValues.clear();
 
 		SizedArray<BfExpression*, 2> argExprs;
@@ -21969,9 +21973,15 @@ void BfExprEvaluator::HandleIndexerExpression(BfIndexerExpression* indexerExpr,
 			BfPropertyDef* foundProp = NULL;
 			BfTypeInstance* foundPropTypeInst = NULL;
 
-			auto curCheckType = startCheckTypeInst;
-			while (curCheckType != NULL)
+			BfBaseClassWalker baseClassWalker(target.mType, NULL, mModule);
+			
+			while (true)
 			{
+				auto checkEntry = baseClassWalker.Next();
+				auto curCheckType = checkEntry.mTypeInstance;
+				if (curCheckType == NULL)
+					break;
+
 				BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
 
 				curCheckType->mTypeDef->PopulateMemberSets();
@@ -21993,9 +22003,6 @@ void BfExprEvaluator::HandleIndexerExpression(BfIndexerExpression* indexerExpr,
 						if (checkMethod->mMethodType != BfMethodType_PropertyGetter)
 							continue;
 
-						// For generic params - check interface constraints for an indexer, call that method
-						BF_ASSERT(!target.mType->IsGenericParam());
-
 						if (checkMethod->mIsStatic != wantStatic)
 							continue;
 
@@ -22072,13 +22079,12 @@ void BfExprEvaluator::HandleIndexerExpression(BfIndexerExpression* indexerExpr,
 	bool wantsChecks = checkedKind == BfCheckedKind_Checked;
 	if (checkedKind == BfCheckedKind_NotSet)
 		wantsChecks = mModule->GetDefaultCheckedKind() == BfCheckedKind_Checked;
-
-	//target.mType = mModule->ResolveGenericType(target.mType);
+	
 	if (target.mType->IsVar())
 	{
 		mResult = target;
 		return;
-	}
+	}	
 
 	if ((!target.mType->IsPointer()) && (!target.mType->IsSizedArray()))
 	{

+ 31 - 0
IDEHelper/Tests/src/Indexers.bf

@@ -1,4 +1,10 @@
 using System;
+using System.Collections;
+
+public interface IIndexable<T>
+{
+    T this[int index] { get; set; }
+}
 
 namespace Tests
 {
@@ -87,6 +93,28 @@ namespace Tests
 		    public Span<int> this[Range r] => default;
 		}
 
+		class IndexTest : IIndexable<float>
+		{
+			public float this[int index]
+			{
+				get
+				{
+					return index;
+				}
+
+				set
+				{
+
+				}
+			}
+		}
+
+		public static float Get<T>(T indexable) where T : IIndexable<float>
+		{
+		    float f = indexable[4];
+			return f;
+		}
+
 		[Test]
 		public static void TestBasics()
 		{
@@ -116,6 +144,9 @@ namespace Tests
 
 			Bar bar = scope .();
 			Test.Assert(bar[3] == 9);
+
+			IndexTest it = scope .();
+			Test.Assert(it[5] == 5.0f);
 		}
 	}
 }