diff --git a/IDEHelper/Compiler/BfAutoComplete.h b/IDEHelper/Compiler/BfAutoComplete.h index 3dd5fcca..03cc28d8 100644 --- a/IDEHelper/Compiler/BfAutoComplete.h +++ b/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& commas); diff --git a/IDEHelper/Compiler/BfElementVisitor.cpp b/IDEHelper/Compiler/BfElementVisitor.cpp index db2565f3..96c2516c 100644 --- a/IDEHelper/Compiler/BfElementVisitor.cpp +++ b/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); diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index bbe036d4..b6fa733c 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/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) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 3fb1d583..a84444b1 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/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(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); + } } } diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 3c19b5f1..a38a468a 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -249,6 +249,7 @@ public: SizedArray mScopeArgs; Array 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; diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 661f0c9f..b8381998 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/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)); } } diff --git a/IDEHelper/Compiler/BfSourceClassifier.cpp b/IDEHelper/Compiler/BfSourceClassifier.cpp index d52b821a..6123bffe 100644 --- a/IDEHelper/Compiler/BfSourceClassifier.cpp +++ b/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) diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index d17eeaff..f5478505 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/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& callEntr deferredCallEntry = deferredCallEntry->mNext; continue; } - int blockId = -block->GetSrcStart(); + int64 blockId = deferredCallEntry->mBlockId; //auto itr = handledSet.insert(deferredCallEntry); //if (!itr.second)