diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 2ce9bb52..17c44a97 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -2722,6 +2722,11 @@ void BfCompiler::UpdateRevisedTypes() ++typeDefItr; continue; } + + if ((!typeDef->IsGlobalsContainer()) && (mSystem->ContainsNamespace(typeDef->mFullName, typeDef->mProject))) + { + mPassInstance->Fail(StrFormat("The name '%s' is already defined to be a namespace name", typeDef->mFullName.ToString().c_str()), typeDef->mTypeDeclaration->mNameNode); + } bool removedElement = false; auto nextTypeDefItr = typeDefItr; @@ -7082,7 +7087,7 @@ String BfCompiler::GetTypeDefList() result += "c"; else result += "v"; - result += BfTypeUtils::TypeToString(typeDef) + "\n"; + result += BfTypeUtils::TypeToString(typeDef, BfTypeNameFlag_InternalName) + "\n"; } } @@ -7381,7 +7386,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) if (matchHelper.CheckMemberMatch(typeDef, fieldDef->mName)) { result += "F"; - if (BfTypeUtils::TypeToString(result, typeDef, BfTypeNameFlag_HideGlobalName)) + if (BfTypeUtils::TypeToString(result, typeDef, (BfTypeNameFlags)(BfTypeNameFlag_HideGlobalName | BfTypeNameFlag_InternalName))) result += "."; result += fieldDef->mName; matchHelper.AddFieldDef(fieldDef); @@ -7397,7 +7402,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) if (matchHelper.CheckMemberMatch(typeDef, propDef->mName)) { result += "P"; - if (BfTypeUtils::TypeToString(result, typeDef, BfTypeNameFlag_HideGlobalName)) + if (BfTypeUtils::TypeToString(result, typeDef, (BfTypeNameFlags)(BfTypeNameFlag_HideGlobalName | BfTypeNameFlag_InternalName))) result += "."; matchHelper.AddPropertyDef(typeDef, propDef); } @@ -7418,7 +7423,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) if (matchHelper.CheckMemberMatch(typeDef, methodDef->mName)) { result += "M"; - if (BfTypeUtils::TypeToString(result, typeDef, BfTypeNameFlag_HideGlobalName)) + if (BfTypeUtils::TypeToString(result, typeDef, (BfTypeNameFlags)(BfTypeNameFlag_HideGlobalName | BfTypeNameFlag_InternalName))) result += "."; matchHelper.AddMethodDef(methodDef); } @@ -7447,11 +7452,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) if (!matchHelper.MergeFlags(matchFlags)) { continue; - } - - //foundComposite.Set(typeDef->mFullName.mParts, matchIdx + 1, NULL, 0); - - //foundComposite = typeDef->mFullName; + } } if (typeDef->mProject != curProject) @@ -7471,9 +7472,9 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) sprintf(str, "=%d\n", *projectIdPtr); result += str; } - } + } - typeName = BfTypeUtils::TypeToString(typeDef); + typeName = BfTypeUtils::TypeToString(typeDef, BfTypeNameFlag_InternalName); if (matchIdx != -1) { @@ -7505,7 +7506,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) else { result += StrFormat("<%d@", *matchIdxPtr); - } + } } else { @@ -7587,6 +7588,10 @@ String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName) typeName.RemoveToEnd(typeName.length() - 8); isGlobals = true; } + + for (int i = 0; i < (int)typeName.length(); i++) + if (typeName[i] == '+') + typeName[i] = '.'; String result; TypeDefMatchHelper matchHelper(result); diff --git a/IDEHelper/Compiler/BfReducer.cpp b/IDEHelper/Compiler/BfReducer.cpp index dd7b7c91..a7bb710f 100644 --- a/IDEHelper/Compiler/BfReducer.cpp +++ b/IDEHelper/Compiler/BfReducer.cpp @@ -6343,6 +6343,11 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, int depth) doExplicitInterface = true; // Qualified property } } + + // Experimental 'more permissive' explicit interface check + if (endNodeIdx != -1) + doExplicitInterface = true; + if (doExplicitInterface) { auto prevEndNode = mVisitorPos.Get(endNodeIdx - 1); diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index dc372957..519477c5 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -408,20 +408,7 @@ BfFieldInstance::~BfFieldInstance() BfType* BfFieldInstance::GetResolvedType() { - return mResolvedType; - /*if (mType == NULL) - return NULL; - if (!mType->IsGenericParam()) - return mType; - if (!mOwner->IsGenericTypeInstance()) - return mType; - auto genericParamType = (BfGenericParamType*)mType; - auto genericTypeInst = (BfGenericTypeInstance*)mOwner; - if (genericTypeInst->mIsUnspecialized) - return mType; - if (genericParamType->mGenericParamKind == BfGenericParamKind_Type) - return genericTypeInst->mTypeGenericArguments[genericParamType->mGenericParamIdx]; - return mType;*/ + return mResolvedType; } void BfFieldInstance::SetResolvedType(BfType* type) @@ -429,6 +416,36 @@ void BfFieldInstance::SetResolvedType(BfType* type) mResolvedType = type; } +////////////////////////////////////////////////////////////////////////// + +int64 BfDeferredMethodCallData::GenerateMethodId(BfModule* module, int64 methodId) +{ + // The mMethodId MUST be unique within a given deferred method processor. We are even more conservative, making it + // unique per module + if (module->mDeferredMethodIds.Add(methodId)) + { + return methodId; + } + else + { + // Ideally the passed in methodId just works, otherwise -- + // We hope to create a hash that will hopefully be globally unique. If it isn't then it just means we will end up with two + // conflicting debug info definitions for the same name, which is not an error but may cause a debugger to show the + // wrong one to the user. Does not affect runtime correctness. + int64 checkId = Hash64(module->mModuleName.c_str(), (int)module->mModuleName.length(), module->mDeferredMethodIds.size()); + while (true) + { + if (!module->mDeferredMethodIds.Contains(checkId)) + break; + checkId += 0x100; + } + module->mDeferredMethodIds.Add(checkId); + return checkId; + } +} + +////////////////////////////////////////////////////////////////////////// + BfMethodCustomAttributes::~BfMethodCustomAttributes() { delete mCustomAttributes; @@ -3720,13 +3737,16 @@ String BfTypeUtils::TypeToString(BfTypeDef* typeDef, BfTypeNameFlags typeNameFla bool BfTypeUtils::TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFlags typeNameFlags) { auto checkTypeDef = typeDef; - bool needsDot = false; + char needsSep = 0; if (checkTypeDef->mOuterType != NULL) { if (TypeToString(str, checkTypeDef->mOuterType, typeNameFlags)) { - needsDot = true; + if ((typeNameFlags & BfTypeNameFlag_InternalName) != 0) + needsSep = '+'; + else + needsSep = '.'; } } else @@ -3734,16 +3754,17 @@ bool BfTypeUtils::TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFl if (((typeNameFlags & BfTypeNameFlag_OmitNamespace) == 0) && (!typeDef->mNamespace.IsEmpty())) { typeDef->mNamespace.ToString(str); - needsDot = true; + needsSep = '.'; } } + + if (needsSep != 0) + str += needsSep; if (((typeNameFlags & BfTypeNameFlag_HideGlobalName) != 0) && (typeDef->IsGlobalsContainer())) return false; - - if (needsDot) - str += "."; - typeDef->mName->ToString(str); + + typeDef->mName->ToString(str); if (typeDef->mGenericParamDefs.size() != 0) { diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 4ca4829e..06983809 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -576,6 +576,8 @@ public: mSize = 0; mMethodId = 0; } + + static int64 GenerateMethodId(BfModule* module, int64 methodId); }; class BfMethodCustomAttributes diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 50fd08af..d17eeaff 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -178,7 +178,14 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc if (deferredCallEntry->mDeferredBlock != NULL) { - int blockId = -deferredCallEntry->mDeferredBlock->GetSrcStart(); + HashContext hashCtx; + hashCtx.Mixin(deferredCallEntry->mDeferredBlock->GetSrcStart()); + + auto parserData = deferredCallEntry->mDeferredBlock->GetParserData(); + if (parserData != NULL) + hashCtx.MixinStr(parserData->mFileName); + + int64 blockId = BfDeferredMethodCallData::GenerateMethodId(this, hashCtx.Finish64()); auto deferType = deferredCallEntryType; @@ -200,7 +207,7 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc SizedArray llvmTypes; SizedArray diFieldTypes; - + typeName = StrFormat("_BF_DeferredData_%s", BfTypeUtils::HashEncode64(blockId).c_str()); auto valueType = ResolveTypeDef(mCompiler->mValueTypeTypeDef); @@ -286,27 +293,8 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc { deferredMethodCallData = new BfDeferredMethodCallData(); mDeferredMethodCallData[methodInstance] = deferredMethodCallData; - - if (mDeferredMethodIds.Add(methodInstance->mIdHash)) - { - deferredMethodCallData->mMethodId = methodInstance->mIdHash; - } - else - { - // Try to create a hash that will hopefully be globally unique. If it isn't then it just means we will end up with two - // conflicting debug info definitions for the same name, which is not an error but may cause a debugger to show the - // wrong one to the user. Does not affect runtime correctness. - int64 checkId = Hash64(mModuleName.c_str(), (int)mModuleName.length(), mDeferredMethodIds.size()); - while (true) - { - if (!mDeferredMethodIds.Contains(checkId)) - break; - checkId += 0x100; - } - mDeferredMethodIds.Add(checkId); - deferredMethodCallData->mMethodId = checkId; - } - + deferredMethodCallData->mMethodId = BfDeferredMethodCallData::GenerateMethodId(this, methodInstance->mIdHash); + auto int64Type = GetPrimitiveType(BfTypeCode_Int64); auto methodDef = moduleMethodInstance.mMethodInstance->mMethodDef; auto thisType = moduleMethodInstance.mMethodInstance->mMethodInstanceGroup->mOwner;