Browse Source

Improved deferred type name generation

Brian Fiete 5 years ago
parent
commit
aafefecfa2

+ 17 - 12
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);

+ 5 - 0
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);

+ 42 - 21
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)
 	{

+ 2 - 0
IDEHelper/Compiler/BfResolvedTypeUtils.h

@@ -576,6 +576,8 @@ public:
 		mSize = 0;
 		mMethodId = 0;
 	}
+
+	static int64 GenerateMethodId(BfModule* module, int64 methodId);
 };
 
 class BfMethodCustomAttributes

+ 11 - 23
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<BfIRType, 4> llvmTypes;
 		SizedArray<BfIRMDNode, 8> 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;