Procházet zdrojové kódy

Struct cast fix, deferred block fix

Brian Fiete před 5 roky
rodič
revize
8b17718fed

+ 1 - 0
IDEHelper/Compiler/BfAutoComplete.h

@@ -230,6 +230,7 @@ public:
 
 	void CheckIdentifier(BfIdentifierNode* identifierNode, bool isInExpression = false, bool isUsingDirective = false);
 	bool CheckMemberReference(BfAstNode* target, BfAstNode* dotToken, BfAstNode* memberName, bool onlyShowTypes = false, BfType* expectingType = NULL, bool isUsingDirective = false, bool onlyAttribute = false);
+	bool CheckExplicitInterface(BfTypeInstance* interfaceType, BfAstNode* dotToken, BfAstNode* memberName);
 	void CheckTypeRef(BfTypeReference* typeRef, bool mayBeIdentifier, bool isInExpression = false, bool onlyAttribute = false);
 	void CheckAttributeTypeRef(BfTypeReference* typeRef);
 	void CheckInvocation(BfAstNode* invocationNode, BfTokenNode* openParen, BfTokenNode* closeParen, const BfSizedArray<BfTokenNode*>& commas);	

+ 1 - 1
IDEHelper/Compiler/BfElementVisitor.cpp

@@ -752,7 +752,7 @@ void BfElementVisitor::Visit(BfDeferStatement* deferStmt)
 
 void BfElementVisitor::Visit(BfReturnStatement* returnStmt)
 {
-	Visit(returnStmt->ToBase());
+ 	Visit(returnStmt->ToBase());
 
 	VisitChild(returnStmt->mReturnToken);
 	VisitChild(returnStmt->mExpression);

+ 18 - 4
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -223,7 +223,9 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
 
 		BfType* methodGenericTypeConstraint = NULL;
 		auto _SetGeneric = [&]()
-		{			
+		{	
+			BF_ASSERT((argType == NULL) || (!argType->IsVar()));
+
 			if (mCheckMethodGenericArguments[wantGenericParam->mGenericParamIdx] != argType)
 			{
 				if (methodGenericTypeConstraint != NULL)
@@ -271,7 +273,7 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
 						}
 					}
 				}
-
+				
 				mInferGenericProgressIdx++;
 				mCheckMethodGenericArguments[wantGenericParam->mGenericParamIdx] = argType;
 			}
@@ -1090,6 +1092,8 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfGenericParamInstance* generi
 
 	if (checkArgType == NULL)
 		return false;
+	if (checkArgType->IsVar())
+		return false;
 	
 	(*methodGenericArgs)[genericParamType->mGenericParamIdx] = checkArgType;
 	return true;
@@ -1572,7 +1576,13 @@ NoMatch:
 		if (genericArgumentsSubstitute != &mBestMethodGenericArguments)
 		{
 			if (genericArgumentsSubstitute != NULL)
+			{
 				mBestMethodGenericArguments = *genericArgumentsSubstitute;
+#ifdef _DEBUG
+				for (auto arg : mBestMethodGenericArguments)
+					BF_ASSERT((arg == NULL) || (!arg->IsVar()));
+#endif
+			}
 			else
 				mBestMethodGenericArguments.clear();
 		}
@@ -3020,12 +3030,16 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfIdentifierNode* identifierNode,
 
 void BfExprEvaluator::Visit(BfIdentifierNode* identifierNode)
 {
-	if (GetAutoComplete() != NULL)
-		GetAutoComplete()->CheckIdentifier(identifierNode, true);
+	auto autoComplete = GetAutoComplete();
+	if (autoComplete != NULL)
+		autoComplete->CheckIdentifier(identifierNode, true);
 	
 	mResult = LookupIdentifier(identifierNode);	
 	if ((!mResult) && (mPropDef == NULL))
+	{
+		mModule->CheckTypeRefFixit(identifierNode);
 		mModule->Fail("Identifier not found", identifierNode);
+	}
 }
 
 void BfExprEvaluator::Visit(BfAttributedIdentifierNode* attrIdentifierNode)

+ 51 - 12
IDEHelper/Compiler/BfModule.cpp

@@ -9065,8 +9065,9 @@ String BfModule::MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags
 		BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None;
 		if (!methodInst->mIsUnspecializedVariation && allowResolveGenericParamNames)
 			typeNameFlags = BfTypeNameFlag_ResolveGenericParamNames;		
+		methodName += "[";
 		methodName += TypeToString(methodInst->mMethodInfoEx->mExplicitInterface, typeNameFlags);
-		methodName += ".";
+		methodName += "].";
 	}
 	
 	if (methodDef->mMethodType == BfMethodType_Operator)
@@ -9103,13 +9104,17 @@ String BfModule::MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags
 	}	
 	else if (methodDef->mMethodType == BfMethodType_PropertyGetter)
 	{
-		methodDef->GetRefNode()->ToString(methodName);
+		auto propertyDecl = methodDef->GetPropertyDeclaration();
+		if ((propertyDecl != NULL) && (propertyDecl->mNameNode != NULL))
+			propertyDecl->mNameNode->ToString(methodName);		
 		methodName += " get accessor";
 		return methodName;
 	}
 	else if (methodDef->mMethodType == BfMethodType_PropertySetter)
 	{
-		methodDef->GetRefNode()->ToString(methodName);
+		auto propertyDecl = methodDef->GetPropertyDeclaration();
+		if ((propertyDecl != NULL) && (propertyDecl->mNameNode != NULL))
+			propertyDecl->mNameNode->ToString(methodName);
 		methodName += " set accessor";
 		return methodName;
 	}
@@ -19037,11 +19042,30 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
 	
 	if (methodDef->mExplicitInterface != NULL)
 	{
-		if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
-			mCompiler->mResolvePassData->mAutoComplete->CheckTypeRef(methodDef->mExplicitInterface, false);
-		auto explicitInterface = ResolveTypeRef(methodDef->mExplicitInterface, BfPopulateType_Declaration);
+		auto autoComplete = mCompiler->GetAutoComplete();
+
+		if (autoComplete != NULL)
+			autoComplete->CheckTypeRef(methodDef->mExplicitInterface, false);
+		auto explicitType = ResolveTypeRef(methodDef->mExplicitInterface, BfPopulateType_Declaration);
+		BfTypeInstance* explicitInterface = NULL;
+		if (explicitType != NULL)
+			explicitInterface = explicitType->ToTypeInstance();
 		if (explicitInterface != NULL)
+		{			
 			mCurMethodInstance->GetMethodInfoEx()->mExplicitInterface = explicitInterface->ToTypeInstance();
+			if (autoComplete != NULL)
+			{
+				BfTokenNode* dotToken = NULL;
+				BfAstNode* nameNode = NULL;
+				if (auto methodDeclaration = BfNodeDynCast<BfMethodDeclaration>(methodDef->mMethodDeclaration))
+				{
+					dotToken = methodDeclaration->mExplicitInterfaceDotToken;
+					nameNode = methodDeclaration->mNameNode;
+				}
+				
+				autoComplete->CheckExplicitInterface(explicitInterface, dotToken, nameNode);
+			}
+		}
 		if ((mCurMethodInstance->mMethodInfoEx != NULL) && (mCurMethodInstance->mMethodInfoEx->mExplicitInterface != NULL))
 		{
 			bool interfaceFound = false;
@@ -20357,7 +20381,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
 			continue;
 
 		bool hadMatch = false;
-		bool hadNameMatch = false;		
+		BfMethodInstance* hadNameMatch = NULL;
 		BfType* expectedReturnType = NULL;
 		
 		bool showedError = false;
@@ -20394,7 +20418,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
 				continue;
 			}
 			if (iMethodInst->mMethodDef->mName == methodInstance->mMethodDef->mName)
-				hadNameMatch = true;								
+				hadNameMatch = iMethodInst;
 
 			bool doesMethodSignatureMatch = CompareMethodSignatures(iMethodInst, methodInstance);
 				
@@ -20467,16 +20491,31 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
 			}
 
 			checkMethodDef = checkMethodDef->mNextWithSameName;
-		}
+		}		
 
 		if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mExplicitInterface == ifaceInst) && (!hadMatch) && (!showedError))
 		{	
 			if (expectedReturnType != NULL)
 				Fail(StrFormat("Wrong return type, expected '%s'", TypeToString(expectedReturnType).c_str()), declaringNode, true);
-			else if (hadNameMatch)
-				Fail("Method parameters don't match interface method", declaringNode, true);
+			else if (hadNameMatch != NULL)
+			{
+				auto error = Fail("Method parameters don't match interface method", declaringNode, true);
+				if (error != NULL)
+					mCompiler->mPassInstance->MoreInfo("See interface method declaration", hadNameMatch->mMethodDef->GetRefNode());
+			}
 			else
-				Fail("Method name not found in interface", methodDef->GetRefNode(), true);
+			{
+				auto propertyDecl = methodDef->GetPropertyDeclaration();
+				if (propertyDecl != NULL)
+				{
+					auto propertyMethodDecl = methodDef->GetPropertyMethodDeclaration();
+
+					Fail(StrFormat("Property '%s' %s accessor not defined in interface '%s'", propertyDecl->mNameNode->ToString().c_str(),
+						(methodDef->mMethodType == BfMethodType_PropertyGetter) ? "get" : "set", TypeToString(ifaceInst).c_str()), methodDef->GetRefNode(), true);
+				}
+				else
+					Fail(StrFormat("Method '%s' not found in interface '%s'", methodDef->mName.c_str(), TypeToString(ifaceInst).c_str()), methodDef->GetRefNode(), true);
+			}
 		}
 	}
 

+ 2 - 0
IDEHelper/Compiler/BfModule.h

@@ -249,6 +249,7 @@ public:
 	SizedArray<BfIRValue, 1> mScopeArgs;
 	Array<BfDeferredCapture> mCaptures;	
 	BfBlock* mDeferredBlock;
+	int64 mBlockId;
 	int mHandlerCount;
 	bool mBypassVirtual;
 	bool mDoNullCheck;
@@ -267,6 +268,7 @@ public:
 		mNext = NULL;
 		mSrcNode = NULL;
 		mDeferredBlock = NULL;
+		mBlockId = -1;
 		mHandlerCount = 0;
 		mArgsNeedLoad = false;
 		mCastThis = false;

+ 5 - 0
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -8079,6 +8079,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
 			{
 				if (toType->IsValuelessType())
 					return BfIRValue::sValueless;
+				if (ignoreWrites)
+					return mBfIRBuilder->GetFakeVal();
+								
+				typedVal = MakeAddressable(typedVal);
+				return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(toTypeInstance));
 			}
 		}
 

+ 2 - 0
IDEHelper/Compiler/BfSourceClassifier.cpp

@@ -250,12 +250,14 @@ void BfSourceClassifier::Visit(BfThisExpression* thisExpr)
 {
 	HandleLeafNode(thisExpr);
 	Visit((BfAstNode*)thisExpr);
+	SetElementType(thisExpr, BfSourceElementType_Keyword);
 }
 
 void BfSourceClassifier::Visit(BfBaseExpression* baseExpr)
 {
 	HandleLeafNode(baseExpr);
 	Visit((BfAstNode*)baseExpr);
+	SetElementType(baseExpr, BfSourceElementType_Keyword);
 }
 
 void BfSourceClassifier::Visit(BfMemberReferenceExpression* memberRefExpr)

+ 2 - 1
IDEHelper/Compiler/BfStmtEvaluator.cpp

@@ -186,6 +186,7 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc
 			hashCtx.MixinStr(parserData->mFileName);
 		
 		int64 blockId = BfDeferredMethodCallData::GenerateMethodId(this, hashCtx.Finish64());
+		deferredCallEntry->mBlockId = blockId;
 
 		auto deferType = deferredCallEntryType;
 
@@ -797,7 +798,7 @@ void BfModule::EmitDeferredCallProcessor(SLIList<BfDeferredCallEntry*>& callEntr
 			deferredCallEntry = deferredCallEntry->mNext;
 			continue;
 		}
-		int blockId = -block->GetSrcStart();
+		int64 blockId = deferredCallEntry->mBlockId;
 
 		//auto itr = handledSet.insert(deferredCallEntry);
 		//if (!itr.second)