From 0b20ef867bc5e7c81dfc4cfbab78de4e0b87c676 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 16 Sep 2020 04:37:28 -0700 Subject: [PATCH] Support for matching interface conformance in distinct build options --- IDE/src/ui/BuildPropertiesDialog.bf | 16 +++++-- IDE/src/ui/TypeWildcardEditWidget.bf | 23 +++++++++- IDEHelper/Compiler/BfExprEvaluator.cpp | 10 ++++- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 52 ++++++++++++++++------ IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 8 ++-- IDEHelper/Compiler/BfSystem.cpp | 3 +- 6 files changed, 87 insertions(+), 25 deletions(-) diff --git a/IDE/src/ui/BuildPropertiesDialog.bf b/IDE/src/ui/BuildPropertiesDialog.bf index 58310662..c8a0134d 100644 --- a/IDE/src/ui/BuildPropertiesDialog.bf +++ b/IDE/src/ui/BuildPropertiesDialog.bf @@ -267,10 +267,20 @@ namespace IDE.ui else { bool isValid = true; - for (let typeName in typeNames.Split(';')) + for (var typeName in typeNames.Split(';')) { - if ((!typeNames.StartsWith("@")) && (!gApp.mBfResolveCompiler.VerifyTypeName(scope String(typeName), -1))) - isValid = false; + if (!typeNames.StartsWith("@")) + { + while (!typeName.IsEmpty) + { + if ((typeName[0] != ':') && (!typeName[0].IsWhiteSpace)) + break; + typeName.RemoveFromStart(1); + } + + if (!gApp.mBfResolveCompiler.VerifyTypeName(scope String(typeName), -1)) + isValid = false; + } } subItem.mTextColor = isValid ? 0xFFFFFFFF : 0xFFFF8080; propEntry.mColorOverride = subItem.mTextColor; diff --git a/IDE/src/ui/TypeWildcardEditWidget.bf b/IDE/src/ui/TypeWildcardEditWidget.bf index f10696f2..5444f4a8 100644 --- a/IDE/src/ui/TypeWildcardEditWidget.bf +++ b/IDE/src/ui/TypeWildcardEditWidget.bf @@ -34,6 +34,14 @@ namespace IDE.ui editOffset = semiPos + 1; } + while (editOffset < editText.Length) + { + char8 c = editText[editOffset]; + if ((c != ':') && (!c.IsWhiteSpace)) + break; + editOffset++; + } + editText.Remove(0, editOffset); cursorPos -= editOffset; // @@ -47,7 +55,9 @@ namespace IDE.ui if (editText.StartsWith("@")) isValid = true; else + { isValid = gApp.mBfResolveCompiler.VerifyTypeName(editText, cursorPos); + } for (int ofs < editText.Length) { @@ -82,14 +92,23 @@ namespace IDE.ui text[i].mDisplayTypeId = 0; } - for (let typeName in editText.Split(';')) + for (var typeName in editText.Split(';')) { + int startOfs = 0; + while (!typeName.IsEmpty) + { + if ((typeName[0] != ':') && (!typeName[0].IsWhiteSpace)) + break; + typeName.RemoveFromStart(1); + startOfs++; + } + bool isValid = gApp.mBfResolveCompiler.VerifyTypeName(scope String(typeName), -1); if (!isValid) { for (int ofs < typeName.Length) { - text[@typeName.Pos + ofs].mDisplayTypeId = 1; + text[@typeName.Pos + startOfs + ofs].mDisplayTypeId = 1; } } } diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 62c669bf..dbe9c218 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -13051,8 +13051,14 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa } else if (primStructType->IsSplattable()) { - BF_ASSERT(target.IsSplat()); - target.mKind = BfTypedValueKind_SplatHead; + BF_ASSERT(target.IsSplat() || target.mValue.IsFake()); + if (target.IsSplat()) + target.mKind = BfTypedValueKind_SplatHead; + else + { + if (!target.mValue.IsFake()) + mModule->FailInternal("MakeCallableTarget splat fail", targetSrc); + } } } diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index c3aca288..d424cfa3 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -1673,9 +1673,10 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn int typeOptionsCount = (int)mContext->mSystem->mTypeOptions.size(); if (checkTypeName) - { - auto _CheckTypeName = [&](const StringImpl& typeName) - { + { + auto _CheckType = [&](BfType* type) + { + StringImpl typeName = TypeToString(type); for (int optionIdx = 0; optionIdx < (int)mContext->mSystem->mTypeOptions.size(); optionIdx++) { auto& typeOptions = mContext->mSystem->mTypeOptions[optionIdx]; @@ -1686,7 +1687,35 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn int filterIdx = 0; int typeNameIdx = 0; - if (BfCheckWildcard(filter, typeName)) + if (filter.StartsWith(':')) + { + BfTypeInstance* typeInst = type->ToTypeInstance(); + if (typeInst != NULL) + { + int startPos = 1; + for (; startPos < (int)filter.length(); startPos++) + if (filter[startPos] != ' ') + break; + String checkFilter; + checkFilter.Reference(filter.c_str() + startPos, filter.mLength - startPos); + + BfTypeInstance* checkTypeInst = typeInst; + while (checkTypeInst != NULL) + { + for (auto& iface : checkTypeInst->mInterfaces) + { + StringT<128> ifaceName = TypeToString(iface.mInterfaceType); + if (BfCheckWildcard(checkFilter, ifaceName)) + matched = true; + break; + } + checkTypeInst = checkTypeInst->mBaseType; + } + if (matched) + break; + } + } + else if (BfCheckWildcard(filter, typeName)) { matched = true; break; @@ -1702,9 +1731,8 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn { auto underlyingType = typeInstance->GetUnderlyingType(); if (underlyingType != NULL) - { - String typeName = TypeToString(underlyingType); - _CheckTypeName(typeName); + { + _CheckType(underlyingType); } else { @@ -1716,13 +1744,11 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn { BF_ASSERT(typeInstance->IsGenericTypeInstance()); auto innerType = typeInstance->mGenericTypeInfo->mTypeGenericArguments[0]; - auto ptrType = CreatePointerType(innerType); - String typeName = TypeToString(ptrType); - _CheckTypeName(typeName); + auto ptrType = CreatePointerType(innerType); + _CheckType(ptrType); } - - String typeName = TypeToString(typeInstance); - _CheckTypeName(typeName); + + _CheckType(typeInstance); } int matchedIdx = -1; diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 4229b63e..fb452cd4 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -1978,10 +1978,11 @@ bool BfTypeInstance::IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProje bool BfTypeInstance::WantsGCMarking() { + BF_ASSERT(mTypeDef->mTypeCode != BfTypeCode_Extension); if (IsObjectOrInterface()) return true; if ((IsEnum()) && (!IsPayloadEnum())) - return false; + return false; BF_ASSERT(mDefineState >= BfTypeDefineState_Defined); return mWantsGCMarking; } @@ -2198,13 +2199,14 @@ BfType* BfTypeInstance::GetUnderlyingType() bool BfTypeInstance::IsValuelessType() { + BF_ASSERT(mTypeDef->mTypeCode != BfTypeCode_Extension); if ((mTypeDef->mTypeCode == BfTypeCode_Object) || (mTypeDef->mTypeCode == BfTypeCode_Interface)) { return false; } if (mTypeDef->mIsOpaque) - return false; - + return false; + BF_ASSERT(mDefineState >= BfTypeDefineState_Defined); BF_ASSERT(mInstSize >= 0); if (mInstSize == 0) diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 6c1e5a8b..e8e77ab2 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -2617,12 +2617,11 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) BF_ASSERT(typeDef->mFullNameEx == nextTypeDef->mFullNameEx); typeDef->mProtection = nextTypeDef->mProtection; - if ((typeDef->mTypeCode != BfTypeCode_Extension) && (!typeDef->mIsCombinedPartial)) - BF_ASSERT(nextTypeDef->mTypeCode != BfTypeCode_Extension); BF_ASSERT(typeDef->mTypeCode == nextTypeDef->mTypeCode); typeDef->mTypeCode = nextTypeDef->mTypeCode; + typeDef->mIsAlwaysInclude = nextTypeDef->mIsAlwaysInclude; typeDef->mIsNoDiscard = nextTypeDef->mIsNoDiscard; typeDef->mIsPartial = nextTypeDef->mIsPartial;