소스 검색

Emitted code refactor - copied typedefs

Brian Fiete 3 년 전
부모
커밋
0bfa411d22

+ 5 - 3
IDEHelper/Compiler/BfAutoComplete.cpp

@@ -445,7 +445,7 @@ bool BfAutoComplete::IsAttribute(BfTypeInstance* typeInst)
 	auto checkTypeInst = typeInst;
 	auto checkTypeInst = typeInst;
 	while (checkTypeInst != NULL)
 	while (checkTypeInst != NULL)
 	{
 	{
-		if (checkTypeInst->mTypeDef == mModule->mCompiler->mAttributeTypeDef)
+		if (checkTypeInst->mTypeDef->GetLatest() == mModule->mCompiler->mAttributeTypeDef->GetLatest())
 			return true;
 			return true;
 
 
 		checkTypeInst = checkTypeInst->mBaseType;
 		checkTypeInst = checkTypeInst->mBaseType;
@@ -515,6 +515,8 @@ void BfAutoComplete::AddMethod(BfTypeInstance* typeInstance, BfMethodDef* method
 
 
 void BfAutoComplete::AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bool onlyAttribute)
 void BfAutoComplete::AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bool onlyAttribute)
 {
 {
+	BF_ASSERT(typeDef->mDefState != BfTypeDef::DefState_Emitted);
+
 	if (typeDef->mTypeDeclaration == NULL)
 	if (typeDef->mTypeDeclaration == NULL)
 		return;
 		return;
 
 
@@ -615,9 +617,9 @@ void BfAutoComplete::AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& f
 void BfAutoComplete::AddCurrentTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate, bool onlyAttribute)
 void BfAutoComplete::AddCurrentTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate, bool onlyAttribute)
 {	
 {	
 	if (typeInst != mModule->mCurTypeInstance)
 	if (typeInst != mModule->mCurTypeInstance)
-		AddTypeDef(typeInst->mTypeDef, filter, onlyAttribute);
+		AddTypeDef(typeInst->mTypeDef->GetDefinition(), filter, onlyAttribute);
 
 
-	auto typeDef = typeInst->mTypeDef;
+	auto typeDef = typeInst->mTypeDef->GetDefinition();
 	for (auto nestedTypeDef : typeDef->mNestedTypes)
 	for (auto nestedTypeDef : typeDef->mNestedTypes)
 	{
 	{
 		if (nestedTypeDef->mIsPartial)
 		if (nestedTypeDef->mIsPartial)

+ 8 - 5
IDEHelper/Compiler/BfCompiler.cpp

@@ -2935,7 +2935,7 @@ void BfCompiler::UpdateRevisedTypes()
 		auto typeDef = *typeDefItr;
 		auto typeDef = *typeDefItr;
 		auto origTypeDef = typeDef;
 		auto origTypeDef = typeDef;
 		if (typeDef->mNextRevision != NULL)
 		if (typeDef->mNextRevision != NULL)
-			typeDef = typeDef->mNextRevision;		
+			typeDef = typeDef->mNextRevision;
 		if (typeDef->mDupDetectedRevision == mRevision)
 		if (typeDef->mDupDetectedRevision == mRevision)
 		{
 		{
 			++typeDefItr;
 			++typeDefItr;
@@ -4750,6 +4750,7 @@ void BfCompiler::GetSymbolReferences()
 		if ((typeDef == NULL) || (typeDef->mTypeDeclaration == NULL))
 		if ((typeDef == NULL) || (typeDef->mTypeDeclaration == NULL))
 			return;
 			return;
 
 
+		typeDef = typeDef->GetLatest();
 		mResolvePassData->mSymbolReferenceTypeDef = typeDef;
 		mResolvePassData->mSymbolReferenceTypeDef = typeDef;
 		auto replaceType = module->ResolveTypeDef(typeDef, BfPopulateType_IdentityNoRemapAlias);
 		auto replaceType = module->ResolveTypeDef(typeDef, BfPopulateType_IdentityNoRemapAlias);
 		module->PopulateType(replaceType);
 		module->PopulateType(replaceType);
@@ -4764,7 +4765,7 @@ void BfCompiler::GetSymbolReferences()
 				for (auto type : mContext->mResolvedTypes)
 				for (auto type : mContext->mResolvedTypes)
 				{
 				{
 					auto typeInst = type->ToTypeInstance();
 					auto typeInst = type->ToTypeInstance();
-					if ((typeInst != replaceTypeInst) && (typeInst != NULL) && (typeInst->mTypeDef == typeDef))
+					if ((typeInst != replaceTypeInst) && (typeInst != NULL) && (typeInst->mTypeDef->GetLatest() == typeDef))
 						AddDepsToRebuildTypeList(typeInst, rebuildTypeInstList);
 						AddDepsToRebuildTypeList(typeInst, rebuildTypeInstList);
 				}
 				}
 			}
 			}
@@ -8711,11 +8712,13 @@ int BfCompiler::GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer)
 		return -1;
 		return -1;
 
 
 	auto typeDef = typeInst->mTypeDef;
 	auto typeDef = typeInst->mTypeDef;
-
-	if (typeDef->mEmitParser == NULL)
+	if (typeDef->mEmitParent == NULL)
+		return -1;
+	auto emitParser = typeDef->mSource->ToParser();
+	if (emitParser == NULL)
 		return -1;
 		return -1;
 	if (outBuffer != NULL)
 	if (outBuffer != NULL)
-		outBuffer->Append(typeDef->mEmitParser->mSrc, typeDef->mEmitParser->mSrcLength);
+		outBuffer->Append(emitParser->mSrc, emitParser->mSrcLength);
 	return typeInst->mRevision;
 	return typeInst->mRevision;
 }
 }
 
 

+ 1 - 1
IDEHelper/Compiler/BfConstResolver.cpp

@@ -116,7 +116,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
 	if ((mResult) && (wantType != NULL))
 	if ((mResult) && (wantType != NULL))
 	{
 	{
 		auto typeInst = mResult.mType->ToTypeInstance();
 		auto typeInst = mResult.mType->ToTypeInstance();
-		if ((typeInst != NULL) && (typeInst->mTypeDef == mModule->mCompiler->mStringTypeDef))
+		if ((typeInst != NULL) && (typeInst->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
 		{
 		{
 			BfType* toType = wantType;
 			BfType* toType = wantType;
 			if (toType == NULL)
 			if (toType == NULL)

+ 32 - 7
IDEHelper/Compiler/BfContext.cpp

@@ -726,6 +726,8 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
 
 
 void BfContext::HandleChangedTypeDef(BfTypeDef* typeDef, bool isAutoCompleteTempType)
 void BfContext::HandleChangedTypeDef(BfTypeDef* typeDef, bool isAutoCompleteTempType)
 {
 {
+	BF_ASSERT(typeDef->mEmitParent == NULL);
+
 	if ((mCompiler->mResolvePassData == NULL) || (!typeDef->HasSource(mCompiler->mResolvePassData->mParser)))
 	if ((mCompiler->mResolvePassData == NULL) || (!typeDef->HasSource(mCompiler->mResolvePassData->mParser)))
 		return;
 		return;
 
 
@@ -899,7 +901,7 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
 		RebuildDependentTypes(typeInst);
 		RebuildDependentTypes(typeInst);
 	}	
 	}	
 	
 	
-	if (typeInst->mTypeDef->mDefState == BfTypeDef::DefState_Deleted)
+	if (typeInst->mTypeDef->GetDefinition()->mDefState == BfTypeDef::DefState_Deleted)
 		return;	
 		return;	
 		
 		
 	if (typeInst->mDefineState == BfTypeDefineState_Undefined)
 	if (typeInst->mDefineState == BfTypeDefineState_Undefined)
@@ -1053,7 +1055,14 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
 	delete typeInst->mTypeInfoEx;
 	delete typeInst->mTypeInfoEx;
 	typeInst->mTypeInfoEx = NULL;
 	typeInst->mTypeInfoEx = NULL;
 	
 	
-	typeInst->mTypeDef->ClearEmitted();
+	if (typeInst->mTypeDef->mEmitParent != NULL)
+	{
+		auto emitTypeDef = typeInst->mTypeDef;
+		typeInst->mTypeDef = emitTypeDef->mEmitParent;
+		delete emitTypeDef;
+	}
+
+	//typeInst->mTypeDef->ClearEmitted();
 	for (auto localMethod : typeInst->mOwnedLocalMethods)
 	for (auto localMethod : typeInst->mOwnedLocalMethods)
 		delete localMethod;
 		delete localMethod;
 	typeInst->mOwnedLocalMethods.Clear();
 	typeInst->mOwnedLocalMethods.Clear();
@@ -1892,12 +1901,21 @@ void BfContext::UpdateRevisedTypes()
 			continue;
 			continue;
 
 
 		auto typeDef = typeInst->mTypeDef;		
 		auto typeDef = typeInst->mTypeDef;		
+
+		if (typeDef->mEmitParent != NULL)
+		{
+			auto emitTypeDef = typeDef;
+			typeDef = typeDef->mEmitParent;
+			if (typeDef->mNextRevision != NULL)
+				emitTypeDef->mDefState = BfTypeDef::DefState_EmittedDirty;
+		}
+
 		if (typeDef->mProject->mDisabled)
 		if (typeDef->mProject->mDisabled)
 		{
 		{
 			DeleteType(type);
 			DeleteType(type);
 			continue;
 			continue;
 		}
 		}
-
+		
 		typeInst->mRebuildFlags = BfTypeRebuildFlag_None;
 		typeInst->mRebuildFlags = BfTypeRebuildFlag_None;
 						
 						
 		if (typeDef->mIsPartial)
 		if (typeDef->mIsPartial)
@@ -1946,14 +1964,19 @@ void BfContext::UpdateRevisedTypes()
 		auto typeDef = typeInst->mTypeDef;
 		auto typeDef = typeInst->mTypeDef;
 
 
 		bool isTypeDefinedInContext = true;		
 		bool isTypeDefinedInContext = true;		
-		
+
+		if (typeDef->mEmitParent != NULL)
+		{
+			typeDef = typeDef->mEmitParent;
+		}
+
 		if (typeDef->mDefState == BfTypeDef::DefState_Deleted)
 		if (typeDef->mDefState == BfTypeDef::DefState_Deleted)
 		{			
 		{			
 			HandleChangedTypeDef(typeDef);
 			HandleChangedTypeDef(typeDef);
 			DeleteType(typeInst);
 			DeleteType(typeInst);
 			continue;
 			continue;
 		}
 		}
-
+		
 		if (typeDef->mDefState == BfTypeDef::DefState_InlinedInternals_Changed)
 		if (typeDef->mDefState == BfTypeDef::DefState_InlinedInternals_Changed)
 		{
 		{
 			TypeInlineMethodInternalsChanged(typeInst);
 			TypeInlineMethodInternalsChanged(typeInst);
@@ -2569,7 +2592,7 @@ void BfContext::QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkS
 		}		
 		}		
 
 
 		bool allowMismatch = false;
 		bool allowMismatch = false;
-		if ((methodRef.mTypeInstance->mTypeDef == mCompiler->mInternalTypeDef) || (methodRef.mTypeInstance->mTypeDef == mCompiler->mGCTypeDef))
+		if ((methodRef.mTypeInstance->IsInstanceOf(mCompiler->mInternalTypeDef)) || (methodRef.mTypeInstance->IsInstanceOf(mCompiler->mGCTypeDef)))
 			allowMismatch = true;
 			allowMismatch = true;
 
 
 		// The signature hash better not have changed, because if it did then we should have rebuilding 'module'
 		// The signature hash better not have changed, because if it did then we should have rebuilding 'module'
@@ -2577,7 +2600,9 @@ void BfContext::QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkS
 		int newSignatureHash = (int)methodRef.mTypeInstance->mTypeDef->mSignatureHash;
 		int newSignatureHash = (int)methodRef.mTypeInstance->mTypeDef->mSignatureHash;
 		BF_ASSERT((newSignatureHash == methodRef.mSignatureHash) || (allowMismatch));
 		BF_ASSERT((newSignatureHash == methodRef.mSignatureHash) || (allowMismatch));
 
 
-		auto methodDef = methodRef.mTypeInstance->mTypeDef->mMethods[methodRef.mMethodNum];
+		BfMethodDef* methodDef = NULL;
+		if (methodRef.mMethodNum < methodRef.mTypeInstance->mTypeDef->mMethods.mSize)
+			methodDef = methodRef.mTypeInstance->mTypeDef->mMethods[methodRef.mMethodNum];
 
 
 		auto targetContext = methodRef.mTypeInstance->mContext;
 		auto targetContext = methodRef.mTypeInstance->mContext;
 		BfMethodSpecializationRequest* specializationRequest = targetContext->mMethodSpecializationWorkList.Alloc();
 		BfMethodSpecializationRequest* specializationRequest = targetContext->mMethodSpecializationWorkList.Alloc();

+ 1 - 1
IDEHelper/Compiler/BfDefBuilder.cpp

@@ -1815,7 +1815,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
 		outerTypeDef->mNestedTypes.push_back(mCurActualTypeDef);
 		outerTypeDef->mNestedTypes.push_back(mCurActualTypeDef);
 	}
 	}
 
 
-	BfLogSysM("Creating TypeDef %p Hash:%d from TypeDecl: %p Source: %p ResolvePass: %d AutoComplete:%d PrevRevision:%d\n", mCurTypeDef, mSystem->mTypeDefs.GetHash(mCurTypeDef), typeDeclaration, 
+	BfLogSysM("Creating TypeDef %p Hash:%d from TypeDecl: %p Source: %p ResolvePass: %d AutoComplete:%d PrevRevision:%d\n", mCurTypeDef, mCurTypeDef->mHash, typeDeclaration, 
 		typeDeclaration->GetSourceData(), mResolvePassData != NULL, isAutoCompleteTempType, prevRevisionTypeDef);				
 		typeDeclaration->GetSourceData(), mResolvePassData != NULL, isAutoCompleteTempType, prevRevisionTypeDef);				
 	
 	
 	BF_ASSERT(mCurTypeDef->mNameEx == NULL);
 	BF_ASSERT(mCurTypeDef->mNameEx == NULL);

+ 13 - 13
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -285,7 +285,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
 							if (checkArgType->IsGenericTypeInstance())
 							if (checkArgType->IsGenericTypeInstance())
 							{
 							{
 								auto argGenericType = (BfTypeInstance*)checkArgType;
 								auto argGenericType = (BfTypeInstance*)checkArgType;
-								if (argGenericType->mTypeDef == wantGenericType->mTypeDef)
+								if (argGenericType->mTypeDef->GetLatest() == wantGenericType->mTypeDef->GetLatest())
 								{
 								{
 									for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
 									for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
 										InferGenericArgument(methodInstance, argGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], wantGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], BfIRValue());
 										InferGenericArgument(methodInstance, argGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], wantGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], BfIRValue());
@@ -294,7 +294,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
 							else if (checkArgType->IsSizedArray())
 							else if (checkArgType->IsSizedArray())
 							{
 							{
 								auto sizedArrayType = (BfSizedArrayType*)checkArgType;
 								auto sizedArrayType = (BfSizedArrayType*)checkArgType;
-								if (wantGenericType->mTypeDef == mModule->mCompiler->mSizedArrayTypeDef)
+								if (wantGenericType->IsInstanceOf(mModule->mCompiler->mSizedArrayTypeDef))
 								{
 								{
 									InferGenericArgument(methodInstance, sizedArrayType->mElementType, wantGenericType->mGenericTypeInfo->mTypeGenericArguments[0], BfIRValue());
 									InferGenericArgument(methodInstance, sizedArrayType->mElementType, wantGenericType->mGenericTypeInfo->mTypeGenericArguments[0], BfIRValue());
 									auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
 									auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
@@ -305,7 +305,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
 							else if (checkArgType->IsPointer())
 							else if (checkArgType->IsPointer())
 							{
 							{
 								auto pointerType = (BfPointerType*)checkArgType;
 								auto pointerType = (BfPointerType*)checkArgType;
-								if (wantGenericType->mTypeDef == mModule->mCompiler->mPointerTTypeDef)
+								if (wantGenericType->IsInstanceOf(mModule->mCompiler->mPointerTTypeDef))
 								{
 								{
 									InferGenericArgument(methodInstance, pointerType->mElementType, wantGenericType->mGenericTypeInfo->mTypeGenericArguments[0], BfIRValue());
 									InferGenericArgument(methodInstance, pointerType->mElementType, wantGenericType->mGenericTypeInfo->mTypeGenericArguments[0], BfIRValue());
 								}
 								}
@@ -2644,7 +2644,7 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori
 			BfTypeInterfaceEntry* bestIFaceEntry = NULL;
 			BfTypeInterfaceEntry* bestIFaceEntry = NULL;
 			auto checkTypeInst = checkType->ToTypeInstance();			
 			auto checkTypeInst = checkType->ToTypeInstance();			
 
 
-			if (mBestMethodTypeInstance->mTypeDef == mModule->mCompiler->mIHashableTypeDef)
+			if (mBestMethodTypeInstance->IsInstanceOf(mModule->mCompiler->mIHashableTypeDef))
 			{
 			{
 				if ((origTarget != NULL) && (origTarget->mType->IsPointer()) && (staticResult != NULL))
 				if ((origTarget != NULL) && (origTarget->mType->IsPointer()) && (staticResult != NULL))
 				{					
 				{					
@@ -5280,7 +5280,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
 		}
 		}
 	}
 	}
 
 
-	if ((methodInstance->GetOwner()->mTypeDef == mModule->mCompiler->mDeferredCallTypeDef) &&
+	if ((methodInstance->GetOwner()->IsInstanceOf(mModule->mCompiler->mDeferredCallTypeDef)) &&
 		(methodInstance->mMethodDef->mName == "Cancel"))
 		(methodInstance->mMethodDef->mName == "Cancel"))
 	{
 	{
 		if (mModule->mCurMethodState != NULL)
 		if (mModule->mCurMethodState != NULL)
@@ -6545,7 +6545,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
 					if (argValue.mType == mModule->GetPrimitiveType(BfTypeCode_Float))
 					if (argValue.mType == mModule->GetPrimitiveType(BfTypeCode_Float))
 						argValue = mModule->Cast(argValues[argExprIdx].mExpression, argValue, mModule->GetPrimitiveType(BfTypeCode_Double));
 						argValue = mModule->Cast(argValues[argExprIdx].mExpression, argValue, mModule->GetPrimitiveType(BfTypeCode_Double));
 
 
-					if ((typeInst != NULL) && (typeInst->mTypeDef == mModule->mCompiler->mStringTypeDef))
+					if ((typeInst != NULL) && (typeInst->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
 					{
 					{
 						BfType* charType = mModule->GetPrimitiveType(BfTypeCode_Char8);
 						BfType* charType = mModule->GetPrimitiveType(BfTypeCode_Char8);
 						BfType* charPtrType = mModule->CreatePointerType(charType);
 						BfType* charPtrType = mModule->CreatePointerType(charType);
@@ -7423,7 +7423,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
 
 
 	auto methodDef = methodMatcher.mBestMethodDef;
 	auto methodDef = methodMatcher.mBestMethodDef;
 	if (mModule->mCompiler->mResolvePassData != NULL)
 	if (mModule->mCompiler->mResolvePassData != NULL)
-		mModule->mCompiler->mResolvePassData->HandleMethodReference(targetSrc, curTypeInst->mTypeDef, methodDef);
+		mModule->mCompiler->mResolvePassData->HandleMethodReference(targetSrc, curTypeInst->mTypeDef->GetDefinition(), methodDef);
 
 
 	// There should always be a constructor
 	// There should always be a constructor
 	BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
 	BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
@@ -8649,7 +8649,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
 				if (genericParamInstance->mTypeConstraint != NULL)
 				if (genericParamInstance->mTypeConstraint != NULL)
 					typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance();
 					typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance();
 				if ((typeInstConstraint != NULL) &&
 				if ((typeInstConstraint != NULL) &&
-					((typeInstConstraint->mTypeDef == mModule->mCompiler->mDelegateTypeDef) || (typeInstConstraint->mTypeDef == mModule->mCompiler->mFunctionTypeDef)))
+					((typeInstConstraint->IsInstanceOf(mModule->mCompiler->mDelegateTypeDef)) || (typeInstConstraint->IsInstanceOf(mModule->mCompiler->mFunctionTypeDef))))
 				{
 				{
 					MarkResultUsed();
 					MarkResultUsed();
 
 
@@ -14619,7 +14619,7 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN
 		{
 		{
 			for (auto& attrib : customAttrs->mAttributes)
 			for (auto& attrib : customAttrs->mAttributes)
 			{
 			{
-				if (attrib.mType->mTypeDef == mModule->mCompiler->mAlignAttributeTypeDef)
+				if (attrib.mType->IsInstanceOf(mModule->mCompiler->mAlignAttributeTypeDef))
 				{
 				{
 					allocTarget.mAlignOverride = 16; // System conservative default
 					allocTarget.mAlignOverride = 16; // System conservative default
 
 
@@ -14637,7 +14637,7 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN
 						}
 						}
 					}
 					}
 				}
 				}
-				else if (attrib.mType->mTypeDef == mModule->mCompiler->mFriendAttributeTypeDef)				
+				else if (attrib.mType->IsInstanceOf(mModule->mCompiler->mFriendAttributeTypeDef))
 					allocTarget.mIsFriend = true;				
 					allocTarget.mIsFriend = true;				
 			}
 			}
 
 
@@ -16479,7 +16479,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
 				if (!value)
 				if (!value)
 					return;
 					return;
 				auto typeInst = value.mType->ToTypeInstance();
 				auto typeInst = value.mType->ToTypeInstance();
-				if ((typeInst != NULL) && (typeInst->mTypeDef == mModule->mCompiler->mStringTypeDef))
+				if ((typeInst != NULL) && (typeInst->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
 					value = mModule->Cast(arg, value, charPtrType);
 					value = mModule->Cast(arg, value, charPtrType);
 				if ((value.mType->IsFloat()) && (value.mType->mSize != 8)) // Always cast float to double
 				if ((value.mType->IsFloat()) && (value.mType->mSize != 8)) // Always cast float to double
 					value = mModule->Cast(arg, value, mModule->GetPrimitiveType(BfTypeCode_Double));
 					value = mModule->Cast(arg, value, mModule->GetPrimitiveType(BfTypeCode_Double));
@@ -17035,7 +17035,7 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp
 		if (mPropTarget.mType->IsGenericTypeInstance())
 		if (mPropTarget.mType->IsGenericTypeInstance())
 		{
 		{
 			auto genericTypeInst = (BfTypeInstance*)mPropTarget.mType;
 			auto genericTypeInst = (BfTypeInstance*)mPropTarget.mType;
-			if (genericTypeInst->mTypeDef == mModule->mCompiler->mSizedArrayTypeDef)
+			if (genericTypeInst->IsInstanceOf(mModule->mCompiler->mSizedArrayTypeDef))
 			{				
 			{				
 				if (mPropDef->mName == "Count")
 				if (mPropDef->mName == "Count")
 				{
 				{
@@ -20435,7 +20435,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
 				{
 				{
 					auto isValid = false;
 					auto isValid = false;
 					auto genericTypeInst = mResult.mType->ToGenericTypeInstance();
 					auto genericTypeInst = mResult.mType->ToGenericTypeInstance();
-					if ((genericTypeInst != NULL) && (genericTypeInst->mTypeDef == mModule->mCompiler->mSpanTypeDef))
+					if ((genericTypeInst != NULL) && (genericTypeInst->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
 						isValid = true;
 						isValid = true;
 					else if (mResult.mType->IsArray())
 					else if (mResult.mType->IsArray())
 						isValid = true;
 						isValid = true;

+ 38 - 31
IDEHelper/Compiler/BfModule.cpp

@@ -2675,7 +2675,7 @@ bool BfModule::CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* me
 			auto mixinOwner = mCurMethodState->mMixinState->mMixinMethodInstance->GetOwner();
 			auto mixinOwner = mCurMethodState->mMixinState->mMixinMethodInstance->GetOwner();
 			curCheckType = mixinOwner;
 			curCheckType = mixinOwner;
 		}
 		}
-		bool allowPrivate = (curCheckType != NULL) && (memberOwner->mTypeDef == curCheckType->mTypeDef);
+		bool allowPrivate = (curCheckType != NULL) && (memberOwner->IsInstanceOf(curCheckType->mTypeDef));
 		if (curCheckType != NULL)
 		if (curCheckType != NULL)
 			allowPrivate |= IsInnerType(curCheckType->mTypeDef, memberOwner->mTypeDef);
 			allowPrivate |= IsInnerType(curCheckType->mTypeDef, memberOwner->mTypeDef);
 		if (allowPrivate)
 		if (allowPrivate)
@@ -3561,7 +3561,7 @@ bool BfModule::IsAttribute(BfTypeInstance* typeInst)
 	auto checkTypeInst = typeInst;
 	auto checkTypeInst = typeInst;
 	while (checkTypeInst != NULL)
 	while (checkTypeInst != NULL)
 	{
 	{
-		if (checkTypeInst->mTypeDef == mCompiler->mAttributeTypeDef)
+		if (checkTypeInst->IsInstanceOf(mCompiler->mAttributeTypeDef))
 			return true;
 			return true;
 
 
 		checkTypeInst = checkTypeInst->mBaseType;
 		checkTypeInst = checkTypeInst->mBaseType;
@@ -3685,10 +3685,10 @@ bool BfModule::CheckInternalProtection(BfTypeDef* usingTypeDef)
 
 
 	for (auto internalType : internalAccessSet->mTypes)
 	for (auto internalType : internalAccessSet->mTypes)
 	{
 	{
-		auto checkTypeDef = usingTypeDef;
+		auto checkTypeDef = usingTypeDef->GetDefinition();
 		while (checkTypeDef != NULL)
 		while (checkTypeDef != NULL)
 		{
 		{
-			if (checkTypeDef == internalType->mTypeDef)
+			if (checkTypeDef == internalType->mTypeDef->GetDefinition())
 				return true;
 				return true;
 			checkTypeDef = checkTypeDef->mOuterType;
 			checkTypeDef = checkTypeDef->mOuterType;
 		}
 		}
@@ -4222,7 +4222,7 @@ bool BfModule::IsThreadLocal(BfFieldInstance * fieldInstance)
 	{
 	{
 		for (auto customAttr : fieldInstance->mCustomAttributes->mAttributes)
 		for (auto customAttr : fieldInstance->mCustomAttributes->mAttributes)
 		{
 		{
-			if (customAttr.mType->ToTypeInstance()->mTypeDef == mCompiler->mThreadStaticAttributeTypeDef)
+			if (customAttr.mType->ToTypeInstance()->IsInstanceOf(mCompiler->mThreadStaticAttributeTypeDef))
 				return true;			
 				return true;			
 		}
 		}
 	}
 	}
@@ -4429,7 +4429,7 @@ void BfModule::CreateDynamicCastMethod()
 		BfTypeVector genericArgs;
 		BfTypeVector genericArgs;
 		for (int i = 0; i < (int) genericTypeInst->mGenericParamDefs.size(); i++)
 		for (int i = 0; i < (int) genericTypeInst->mGenericParamDefs.size(); i++)
 			genericArgs.push_back(GetGenericParamType(BfGenericParamKind_Type, i));
 			genericArgs.push_back(GetGenericParamType(BfGenericParamKind_Type, i));
-		auto unboundType = ResolveTypeDef(mCurTypeInstance->mTypeDef, genericArgs, BfPopulateType_Declaration);
+		auto unboundType = ResolveTypeDef(mCurTypeInstance->mTypeDef->GetDefinition(), genericArgs, BfPopulateType_Declaration);
 		typeMatches.push_back(unboundType->mTypeId);
 		typeMatches.push_back(unboundType->mTypeId);
 	}
 	}
 
 
@@ -4447,9 +4447,9 @@ void BfModule::CreateDynamicCastMethod()
 		}
 		}
 
 
 		auto innerTypeInst = innerType->ToTypeInstance();
 		auto innerTypeInst = innerType->ToTypeInstance();
-		if ((innerTypeInst->mTypeDef == mCompiler->mSizedArrayTypeDef) ||
-			(innerTypeInst->mTypeDef == mCompiler->mPointerTTypeDef) ||
-			(innerTypeInst->mTypeDef == mCompiler->mMethodRefTypeDef))
+		if ((innerTypeInst->IsInstanceOf(mCompiler->mSizedArrayTypeDef)) ||
+			(innerTypeInst->IsInstanceOf(mCompiler->mPointerTTypeDef)) ||
+			(innerTypeInst->IsInstanceOf(mCompiler->mMethodRefTypeDef)))
 		{
 		{
 			PopulateType(innerTypeInst);
 			PopulateType(innerTypeInst);
 			//TODO: What case was this supposed to handle?
 			//TODO: What case was this supposed to handle?
@@ -6118,7 +6118,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 					auto argType = ctorMethodInstance->GetParamType(argIdx);
 					auto argType = ctorMethodInstance->GetParamType(argIdx);
 					if (argType->IsObject())
 					if (argType->IsObject())
 					{
 					{
-						BF_ASSERT(argType->ToTypeInstance()->mTypeDef == mCompiler->mStringTypeDef);
+						BF_ASSERT(argType->ToTypeInstance()->IsInstanceOf(mCompiler->mStringTypeDef));
 
 
 						int stringId = constant->mInt32;
 						int stringId = constant->mInt32;
 						int* orderedIdPtr;
 						int* orderedIdPtr;
@@ -6980,7 +6980,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 	{
 	{
 		auto genericTypeInstance = typeInstance->ToGenericTypeInstance();
 		auto genericTypeInstance = typeInstance->ToGenericTypeInstance();
 		auto reflectSpecializedGenericType = ResolveTypeDef(mCompiler->mReflectSpecializedGenericType);
 		auto reflectSpecializedGenericType = ResolveTypeDef(mCompiler->mReflectSpecializedGenericType);
-		auto unspecializedType = ResolveTypeDef(typeInstance->mTypeDef);
+		auto unspecializedType = ResolveTypeDef(typeInstance->mTypeDef->GetDefinition());
 
 
 		SizedArray<BfIRValue, 4> resolvedTypes;
 		SizedArray<BfIRValue, 4> resolvedTypes;
 		for (auto typeGenericArg : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
 		for (auto typeGenericArg : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
@@ -7864,7 +7864,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
 					if (convCheckConstraint->IsGenericTypeInstance())
 					if (convCheckConstraint->IsGenericTypeInstance())
 					{
 					{
 						auto convCheckConstraintInst = (BfTypeInstance*)convCheckConstraint;
 						auto convCheckConstraintInst = (BfTypeInstance*)convCheckConstraint;
-						if (convCheckConstraintInst->mTypeDef == mCompiler->mSizedArrayTypeDef)
+						if (convCheckConstraintInst->IsInstanceOf(mCompiler->mSizedArrayTypeDef))
 						{
 						{
 							if (convCheckConstraintInst->mGenericTypeInfo->mTypeGenericArguments[0] == sizedArrayType->mElementType)
 							if (convCheckConstraintInst->mGenericTypeInfo->mTypeGenericArguments[0] == sizedArrayType->mElementType)
 							{
 							{
@@ -9577,17 +9577,18 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar
 	
 	
 	auto irb = mBfIRBuilder;
 	auto irb = mBfIRBuilder;
 
 
+	auto checkBB = irb->CreateBlock("as.check");
+	auto isNull = irb->CreateIsNull(targetValue.mValue);
+	mBfIRBuilder->CreateCondBr(isNull, nullSucceeds ? trueBlock : falseBlock, checkBB);
+
 	if (mIsComptimeModule)
 	if (mIsComptimeModule)
 	{
 	{
+		AddBasicBlock(checkBB);
 		auto callResult = mBfIRBuilder->Comptime_DynamicCastCheck(targetValue.mValue, targetType->mTypeId, mBfIRBuilder->MapType(mContext->mBfObjectType));
 		auto callResult = mBfIRBuilder->Comptime_DynamicCastCheck(targetValue.mValue, targetType->mTypeId, mBfIRBuilder->MapType(mContext->mBfObjectType));
 		auto cmpResult = mBfIRBuilder->CreateCmpNE(callResult, GetDefaultValue(mContext->mBfObjectType));
 		auto cmpResult = mBfIRBuilder->CreateCmpNE(callResult, GetDefaultValue(mContext->mBfObjectType));
 		irb->CreateCondBr(cmpResult, trueBlock, falseBlock);
 		irb->CreateCondBr(cmpResult, trueBlock, falseBlock);
 		return;
 		return;
-	}
-
-	auto checkBB = irb->CreateBlock("as.check");
-	auto isNull = irb->CreateIsNull(targetValue.mValue);
-	mBfIRBuilder->CreateCondBr(isNull, nullSucceeds ? trueBlock : falseBlock, checkBB);
+	}	
 
 
 	auto intType = GetPrimitiveType(BfTypeCode_IntPtr);
 	auto intType = GetPrimitiveType(BfTypeCode_IntPtr);
 	auto intPtrType = CreatePointerType(intType);
 	auto intPtrType = CreatePointerType(intType);
@@ -10045,8 +10046,10 @@ BfMethodInstance* BfModule::GetUnspecializedMethodInstance(BfMethodInstance* met
 	
 	
 	if (methodInstance->mMethodDef->mIsLocalMethod)
 	if (methodInstance->mMethodDef->mIsLocalMethod)
 		return methodInstance;
 		return methodInstance;
+	if (methodInstance->mMethodDef->mDeclaringType->IsEmitted())
+		return methodInstance;
 
 
-	auto unspecializedType = ResolveTypeDef(genericType->mTypeDef);	
+	auto unspecializedType = ResolveTypeDef(genericType->mTypeDef->GetDefinition());	
 	if (unspecializedType == NULL)
 	if (unspecializedType == NULL)
 	{
 	{
 		AssertErrorState();
 		AssertErrorState();
@@ -11055,7 +11058,6 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
 			//  We solve it by having a 'bypass' for known attributes that Object depends on
 			//  We solve it by having a 'bypass' for known attributes that Object depends on
 			if ((attributesDirective->mArguments.empty()) && (autoComplete == NULL) && (attrType != NULL) && (attrType->IsTypeInstance()))
 			if ((attributesDirective->mArguments.empty()) && (autoComplete == NULL) && (attrType != NULL) && (attrType->IsTypeInstance()))
 			{
 			{
-				//if (attrTypeDef == mCompiler->mCReprAttributeTypeDef)
 				if (attrType->IsInstanceOf(mCompiler->mCReprAttributeTypeDef))
 				if (attrType->IsInstanceOf(mCompiler->mCReprAttributeTypeDef))
 				{										
 				{										
 					for (auto methodDef : attrTypeDef->mMethods)
 					for (auto methodDef : attrTypeDef->mMethods)
@@ -11576,7 +11578,7 @@ void BfModule::ProcessCustomAttributeData()
 	auto checkTypeInst = mCurTypeInstance->mBaseType;
 	auto checkTypeInst = mCurTypeInstance->mBaseType;
 	while (checkTypeInst != NULL)
 	while (checkTypeInst != NULL)
 	{
 	{
-		if (checkTypeInst->mTypeDef == mCompiler->mAttributeTypeDef)
+		if (checkTypeInst->IsInstanceOf(mCompiler->mAttributeTypeDef))
 			isAttribute = true;
 			isAttribute = true;
 		checkTypeInst = checkTypeInst->mBaseType;
 		checkTypeInst = checkTypeInst->mBaseType;
 	}
 	}
@@ -11590,7 +11592,7 @@ void BfModule::ProcessCustomAttributeData()
 	{
 	{
 		for (auto& customAttribute : mCurTypeInstance->mCustomAttributes->mAttributes)
 		for (auto& customAttribute : mCurTypeInstance->mCustomAttributes->mAttributes)
 		{			
 		{			
-			if (customAttribute.mType->mTypeDef == mCompiler->mAttributeUsageAttributeTypeDef)
+			if (customAttribute.mType->IsInstanceOf(mCompiler->mAttributeUsageAttributeTypeDef))
 			{
 			{
 				if (customAttribute.mCtorArgs.size() > 0)
 				if (customAttribute.mCtorArgs.size() > 0)
 				{
 				{
@@ -13480,7 +13482,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
 		methodInstance->GetMethodInfoEx()->mForeignType = foreignType;
 		methodInstance->GetMethodInfoEx()->mForeignType = foreignType;
 	}
 	}
 	
 	
-	if ((typeInst->mTypeDef == mCompiler->mValueTypeTypeDef) && (methodDef->mName == BF_METHODNAME_EQUALS))
+	if ((typeInst->IsInstanceOf(mCompiler->mValueTypeTypeDef)) && (methodDef->mName == BF_METHODNAME_EQUALS))
 	{
 	{
 		if (!lookupMethodGenericArguments.empty())
 		if (!lookupMethodGenericArguments.empty())
 		{
 		{
@@ -17281,8 +17283,8 @@ void BfModule::EmitIteratorBlock(bool& skipBody)
 	auto retTypeInst = mCurMethodInstance->mReturnType->ToGenericTypeInstance();	
 	auto retTypeInst = mCurMethodInstance->mReturnType->ToGenericTypeInstance();	
 	if (retTypeInst != NULL)
 	if (retTypeInst != NULL)
 	{
 	{
-		if ((retTypeInst->mTypeDef == mCompiler->mGenericIEnumerableTypeDef) || 
-			(retTypeInst->mTypeDef == mCompiler->mGenericIEnumeratorTypeDef))
+		if ((retTypeInst->IsInstanceOf(mCompiler->mGenericIEnumerableTypeDef)) || 
+			(retTypeInst->IsInstanceOf(mCompiler->mGenericIEnumeratorTypeDef)))
 		{						
 		{						
 			innerRetType = retTypeInst->mGenericTypeInfo->mTypeGenericArguments[0];
 			innerRetType = retTypeInst->mGenericTypeInfo->mTypeGenericArguments[0];
 		}		
 		}		
@@ -17729,7 +17731,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
 					auto typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance();
 					auto typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance();
 					if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()) || 
 					if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()) || 
 						((typeInstConstraint != NULL) && 
 						((typeInstConstraint != NULL) && 
-						 ((typeInstConstraint->mTypeDef == mCompiler->mDelegateTypeDef) || (typeInstConstraint->mTypeDef == mCompiler->mFunctionTypeDef))))
+						 ((typeInstConstraint->IsInstanceOf(mCompiler->mDelegateTypeDef)) || (typeInstConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)))))
 					{
 					{
 						BfLocalVariable* localVar = new BfLocalVariable();
 						BfLocalVariable* localVar = new BfLocalVariable();
 						localVar->mName = paramDef->mName;
 						localVar->mName = paramDef->mName;
@@ -18630,7 +18632,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 		methodState.mGenericTypeBindings = &methodInstance->GetMethodInfoEx()->mGenericTypeBindings;
 		methodState.mGenericTypeBindings = &methodInstance->GetMethodInfoEx()->mGenericTypeBindings;
 	}
 	}
 	else if ((((methodInstance->mMethodInfoEx != NULL) && ((int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size() > dependentGenericStartIdx)) || 
 	else if ((((methodInstance->mMethodInfoEx != NULL) && ((int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size() > dependentGenericStartIdx)) || 
-		((mCurTypeInstance->IsGenericTypeInstance()) && (!isGenericVariation) && (!methodInstance->mMethodDef->mIsLocalMethod))))
+		((mCurTypeInstance->IsGenericTypeInstance()) && (!isGenericVariation) && (!methodInstance->mMethodDef->mIsLocalMethod) && (!methodInstance->mMethodDef->mDeclaringType->IsEmitted()))))
 	{
 	{
 		unspecializedMethodInstance = GetUnspecializedMethodInstance(methodInstance, !methodInstance->mMethodDef->mIsLocalMethod);
 		unspecializedMethodInstance = GetUnspecializedMethodInstance(methodInstance, !methodInstance->mMethodDef->mIsLocalMethod);
 
 
@@ -19590,7 +19592,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 			}
 			}
 			else
 			else
 			{
 			{
-				BF_ASSERT(innerMethodInstance.mMethodInstance->mMethodDef == methodDef);
+				BF_ASSERT(!innerMethodInstance.mMethodInstance->mMethodDef->mDeclaringType->IsEmitted());
+				auto innerMethodDef = innerMethodInstance.mMethodInstance->mMethodDef;
+				if (innerType->mTypeDef->IsEmitted())
+					innerMethodDef = innerType->mTypeDef->mEmitParent->mMethods[innerMethodDef->mIdx];
+
+				BF_ASSERT(innerMethodDef == methodDef);
 
 
 				SizedArray<BfIRValue, 8> innerParams;
 				SizedArray<BfIRValue, 8> innerParams;
 				BfExprEvaluator exprEvaluator(this);
 				BfExprEvaluator exprEvaluator(this);
@@ -19853,7 +19860,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 			skipBody = true;
 			skipBody = true;
 			skipEndChecks = true;
 			skipEndChecks = true;
 		}
 		}
-		else if ((methodDef->mName == BF_METHODNAME_EQUALS) && (typeDef == mCompiler->mValueTypeTypeDef))
+		else if ((methodDef->mName == BF_METHODNAME_EQUALS) && (typeDef->GetDefinition() == mCompiler->mValueTypeTypeDef))
 		{
 		{
 			CreateValueTypeEqualsMethod(false);
 			CreateValueTypeEqualsMethod(false);
 			skipBody = true;
 			skipBody = true;
@@ -22226,7 +22233,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
 
 
 			auto resolvedParamTypeInst = resolvedParamType->ToTypeInstance();
 			auto resolvedParamTypeInst = resolvedParamType->ToTypeInstance();
 
 
-			if ((resolvedParamTypeInst != NULL) && (resolvedParamTypeInst->mTypeDef == mCompiler->mSpanTypeDef))
+			if ((resolvedParamTypeInst != NULL) && (resolvedParamTypeInst->IsInstanceOf(mCompiler->mSpanTypeDef)))
 			{
 			{
 				// Span<T>
 				// Span<T>
 				isValid = true;
 				isValid = true;
@@ -22274,7 +22281,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
 					}
 					}
 					else if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()) ||
 					else if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()) ||
 						((genericParamInstance != NULL) && (typeInstConstraint != NULL) &&
 						((genericParamInstance != NULL) && (typeInstConstraint != NULL) &&
-						 ((typeInstConstraint->mTypeDef == mCompiler->mDelegateTypeDef) || (typeInstConstraint->mTypeDef == mCompiler->mFunctionTypeDef))))
+						 ((typeInstConstraint->IsInstanceOf(mCompiler->mDelegateTypeDef)) || (typeInstConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)))))
 					{										
 					{										
 						mCurMethodInstance->mHadGenericDelegateParams = true;
 						mCurMethodInstance->mHadGenericDelegateParams = true;
 						isValid = true;
 						isValid = true;
@@ -22286,7 +22293,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
 			{
 			{
 				auto paramTypeInst = resolvedParamType->ToTypeInstance();
 				auto paramTypeInst = resolvedParamType->ToTypeInstance();
 				if ((paramTypeInst != NULL) &&
 				if ((paramTypeInst != NULL) &&
-					((paramTypeInst->mTypeDef == mCompiler->mDelegateTypeDef) || (paramTypeInst->mTypeDef == mCompiler->mFunctionTypeDef)))
+					((paramTypeInst->IsInstanceOf(mCompiler->mDelegateTypeDef)) || (paramTypeInst->IsInstanceOf(mCompiler->mFunctionTypeDef))))
 				{
 				{
 					// If we have a 'params T' and 'T' gets specialized with actually 'Delegate' or 'Function' then just ignore it
 					// If we have a 'params T' and 'T' gets specialized with actually 'Delegate' or 'Function' then just ignore it
 					isValid = true;
 					isValid = true;

+ 2 - 2
IDEHelper/Compiler/BfModule.h

@@ -1734,8 +1734,8 @@ public:
 	BfModuleOptions GetModuleOptions();
 	BfModuleOptions GetModuleOptions();
 	BfCheckedKind GetDefaultCheckedKind();
 	BfCheckedKind GetDefaultCheckedKind();
 	void FinishCEParseContext(BfAstNode* refNode, BfTypeInstance* typeInstance, BfCEParseContext* ceParseContext);
 	void FinishCEParseContext(BfAstNode* refNode, BfTypeInstance* typeInstance, BfCEParseContext* ceParseContext);
-	BfCEParseContext CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* activeTypeDef, const StringImpl& src);
-	void UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfTypeDef* activeTypeDef, const StringImpl& ctxString, BfAstNode* refNode);
+	BfCEParseContext CEEmitParse(BfTypeInstance* typeInstance, const StringImpl& src);
+	void UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, const StringImpl& ctxString, BfAstNode* refNode);
 	void HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCustomAttributes* customAttributes, HashSet<BfTypeInstance*> foundAttributes);
 	void HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCustomAttributes* customAttributes, HashSet<BfTypeInstance*> foundAttributes);
 	void CEMixin(BfAstNode* refNode, const StringImpl& src);
 	void CEMixin(BfAstNode* refNode, const StringImpl& src);
 	void ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind);
 	void ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind);

+ 217 - 174
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -506,7 +506,10 @@ void BfModule::CheckInjectNewRevision(BfTypeInstance* typeInstance)
 {
 {
 	if ((typeInstance != NULL) && (typeInstance->mTypeDef != NULL))
 	if ((typeInstance != NULL) && (typeInstance->mTypeDef != NULL))
 	{
 	{
-		if (typeInstance->mTypeDef->mNextRevision != NULL)
+		auto typeDef = typeInstance->mTypeDef;		
+		if (typeDef->mEmitParent != NULL)
+			typeDef = typeDef->mEmitParent;
+		if (typeDef->mNextRevision != NULL)
 		{
 		{
 			// It's possible that our main compiler thread is generating a new typedef while we're autocompleting. This handles that case...
 			// It's possible that our main compiler thread is generating a new typedef while we're autocompleting. This handles that case...
 			if (typeInstance->mDefineState == BfTypeDefineState_Undefined)
 			if (typeInstance->mDefineState == BfTypeDefineState_Undefined)
@@ -519,8 +522,8 @@ void BfModule::CheckInjectNewRevision(BfTypeInstance* typeInstance)
 				}
 				}
 				else
 				else
 				{
 				{
-					mContext->HandleChangedTypeDef(typeInstance->mTypeDef);
-					mSystem->InjectNewRevision(typeInstance->mTypeDef);
+					mContext->HandleChangedTypeDef(typeDef);
+					mSystem->InjectNewRevision(typeDef);
 				}
 				}
 			}
 			}
 			else
 			else
@@ -529,7 +532,10 @@ void BfModule::CheckInjectNewRevision(BfTypeInstance* typeInstance)
 			}
 			}
 		}
 		}
 		if ((!typeInstance->IsDeleting()) && (!mCompiler->IsAutocomplete()))
 		if ((!typeInstance->IsDeleting()) && (!mCompiler->IsAutocomplete()))
-			BF_ASSERT((typeInstance->mTypeDef->mDefState == BfTypeDef::DefState_Defined) || (typeInstance->mTypeDef->mDefState == BfTypeDef::DefState_New));
+			BF_ASSERT((typeDef->mDefState == BfTypeDef::DefState_Defined) || (typeDef->mDefState == BfTypeDef::DefState_New));
+
+ 		if ((typeInstance->mTypeDef->mDefState == BfTypeDef::DefState_EmittedDirty) && (typeInstance->mTypeDef->mEmitParent->mNextRevision == NULL))
+ 			mSystem->UpdateEmittedTypeDef(typeInstance->mTypeDef);
 	}
 	}
 }
 }
 
 
@@ -560,6 +566,8 @@ void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType)
 	{
 	{
 		CheckInjectNewRevision(typeInst);
 		CheckInjectNewRevision(typeInst);
 
 
+		BF_ASSERT(!typeInst->mTypeDef->IsEmitted());
+
 		if (typeInst->mBaseType != NULL)
 		if (typeInst->mBaseType != NULL)
 			BF_ASSERT((typeInst->mBaseType->mRebuildFlags & BfTypeRebuildFlag_Deleted) == 0);
 			BF_ASSERT((typeInst->mBaseType->mRebuildFlags & BfTypeRebuildFlag_Deleted) == 0);
 
 
@@ -1126,6 +1134,11 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
 			else
 			else
 				resolvedTypeRef->mTypeId = mCompiler->mCurTypeId++;
 				resolvedTypeRef->mTypeId = mCompiler->mCurTypeId++;
 
 
+			if (resolvedTypeRef->mTypeId == 2568)
+			{
+				NOP;
+			}
+
 			while (resolvedTypeRef->mTypeId >= (int)mContext->mTypes.size())
 			while (resolvedTypeRef->mTypeId >= (int)mContext->mTypes.size())
 				mContext->mTypes.Add(NULL);
 				mContext->mTypes.Add(NULL);
 			mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef;
 			mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef;
@@ -1413,7 +1426,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
 
 
 		if (mContext->mBfObjectType == NULL)
 		if (mContext->mBfObjectType == NULL)
 		{
 		{
-			if (typeInstance->mTypeDef == mCompiler->mBfObjectTypeDef)
+			if (typeInstance->IsInstanceOf(mCompiler->mBfObjectTypeDef))
 				mContext->mBfObjectType = typeInstance;
 				mContext->mBfObjectType = typeInstance;
 			else if (mCompiler->mBfObjectTypeDef != NULL)
 			else if (mCompiler->mBfObjectTypeDef != NULL)
 				ResolveTypeDef(mCompiler->mBfObjectTypeDef);
 				ResolveTypeDef(mCompiler->mBfObjectTypeDef);
@@ -1836,7 +1849,7 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn
 			}
 			}
 		}
 		}
 
 
-		if ((!typeInstance->IsBoxed()) && (typeInstance->mTypeDef == mCompiler->mPointerTTypeDef))
+		if ((!typeInstance->IsBoxed()) && (typeInstance->IsInstanceOf(mCompiler->mPointerTTypeDef)))
 		{
 		{
 			BF_ASSERT(typeInstance->IsGenericTypeInstance());
 			BF_ASSERT(typeInstance->IsGenericTypeInstance());
 			auto innerType = typeInstance->mGenericTypeInfo->mTypeGenericArguments[0];
 			auto innerType = typeInstance->mGenericTypeInfo->mTypeGenericArguments[0];
@@ -1916,7 +1929,7 @@ void BfModule::SetTypeOptions(BfTypeInstance* typeInstance)
 	typeInstance->mTypeOptionsIdx = GenerateTypeOptions(typeInstance->mCustomAttributes, typeInstance, true);
 	typeInstance->mTypeOptionsIdx = GenerateTypeOptions(typeInstance->mCustomAttributes, typeInstance, true);
 }
 }
 
 
-BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* activeTypeDef, const StringImpl& src)
+BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, const StringImpl& src)
 {
 {
 	BfCEParseContext ceParseContext;
 	BfCEParseContext ceParseContext;
 	ceParseContext.mFailIdx = mCompiler->mPassInstance->mFailedIdx;
 	ceParseContext.mFailIdx = mCompiler->mPassInstance->mFailedIdx;
@@ -1924,45 +1937,56 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef*
 
 
 	bool createdParser = false;
 	bool createdParser = false;
 	int startSrcIdx = 0;
 	int startSrcIdx = 0;
-	if (activeTypeDef->mEmitParser == NULL)
+	
+	BfParser* emitParser = NULL;
+
+	if (typeInstance->mTypeDef->mEmitParent == NULL)
 	{
 	{
-		createdParser = true;
-		BfParser* parser = new BfParser(mSystem, typeInstance->mTypeDef->mProject);
-		parser->mIsEmitted = true;
-		parser->mFileName = typeInstance->mTypeDef->mName->ToString();
+		BF_ASSERT(typeInstance->mTypeDef->mNextRevision == NULL);
+		
+		BfTypeDef* emitTypeDef = new BfTypeDef();
+		emitTypeDef->mEmitParent = typeInstance->mTypeDef;
+		mSystem->CopyTypeDef(emitTypeDef, typeInstance->mTypeDef);
+		emitTypeDef->mDefState = BfTypeDef::DefState_Emitted;
+
+		typeInstance->mTypeDef = emitTypeDef; 
+		
+		createdParser = true;		
+		emitParser = new BfParser(mSystem, typeInstance->mTypeDef->mProject);
+		emitParser->mIsEmitted = true;
+		emitParser->mFileName = typeInstance->mTypeDef->mName->ToString();
 
 
-		BfLogSys(mSystem, "CreateParser (emit): %p\n", parser);
+		BfLogSys(mSystem, "Emit typeDef for type %p created %p parser %p typeDecl %p\n", typeInstance, emitTypeDef, emitParser, emitTypeDef->mTypeDeclaration);
 
 
 		if (mCompiler->mIsResolveOnly)
 		if (mCompiler->mIsResolveOnly)
-			parser->mFileName += "$EmitR$";
+			emitParser->mFileName += "$EmitR$";
 		else
 		else
-			parser->mFileName += "$Emit$";
+			emitParser->mFileName += "$Emit$";
 
 
-		parser->mFileName += StrFormat("%d", typeInstance->mTypeId);
-		if (activeTypeDef->mPartialIdx != -1)
-			parser->mFileName + StrFormat(":%d", activeTypeDef->mPartialIdx);
-
-		parser->mFileName += StrFormat(".bf|%d", typeInstance->mRevision);
-		activeTypeDef->mEmitParser = parser;
-		parser->mRefCount++;
-		parser->SetSource(src.c_str(), src.mLength);
+		emitParser->mFileName += StrFormat("%d", typeInstance->mTypeId);
+		emitParser->mFileName += StrFormat(".bf|%d", typeInstance->mRevision);
+		emitTypeDef->mSource = emitParser;
+		emitParser->mRefCount++;
+		emitParser->SetSource(src.c_str(), src.mLength);
 	}
 	}
 	else
 	else
-	{
-		int idx = activeTypeDef->mEmitParser->AllocChars(src.mLength + 1);
-		memcpy((uint8*)activeTypeDef->mEmitParser->mSrc + idx, src.c_str(), src.mLength + 1);
-		activeTypeDef->mEmitParser->mSrcIdx = idx;
-		activeTypeDef->mEmitParser->mSrcLength = idx + src.mLength;
-		activeTypeDef->mEmitParser->mParserData->mSrcLength = activeTypeDef->mEmitParser->mSrcLength;
+	{		
+		emitParser = typeInstance->mTypeDef->mSource->ToParser();
+
+		int idx = emitParser->AllocChars(src.mLength + 1);
+		memcpy((uint8*)emitParser->mSrc + idx, src.c_str(), src.mLength + 1);
+		emitParser->mSrcIdx = idx;
+		emitParser->mSrcLength = idx + src.mLength;
+		emitParser->mParserData->mSrcLength = emitParser->mSrcLength;
 	}
 	}
 
 
-	activeTypeDef->mEmitParser->Parse(mCompiler->mPassInstance);
-	activeTypeDef->mEmitParser->FinishSideNodes();
+	emitParser->Parse(mCompiler->mPassInstance);
+	emitParser->FinishSideNodes();
 
 
 	if (createdParser)
 	if (createdParser)
 	{
 	{
 		AutoCrit crit(mSystem->mDataLock);
 		AutoCrit crit(mSystem->mDataLock);
-		mSystem->mParsers.Add(activeTypeDef->mEmitParser);
+		mSystem->mParsers.Add(emitParser);
 	}
 	}
 
 
 	return ceParseContext;
 	return ceParseContext;
@@ -1981,14 +2005,14 @@ void BfModule::FinishCEParseContext(BfAstNode* refNode, BfTypeInstance* typeInst
 	}
 	}
 }
 }
 
 
-void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfTypeDef* activeTypeDef, const StringImpl& ctxString, BfAstNode* refNode)
+void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, const StringImpl& ctxString, BfAstNode* refNode)
 {
 {
 	if (ceEmitContext->mEmitData.IsEmpty())
 	if (ceEmitContext->mEmitData.IsEmpty())
 		return;
 		return;
 		
 		
 	String src;
 	String src;
-
-	if (activeTypeDef->mEmitParser != NULL)
+		
+	if (typeInstance->mTypeDef->mEmitParent != NULL)
 		src += "\n\n";
 		src += "\n\n";
 
 
 	src += "// Code emission in ";
 	src += "// Code emission in ";
@@ -1997,27 +2021,30 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn
 	src += ceEmitContext->mEmitData;	
 	src += ceEmitContext->mEmitData;	
 	ceEmitContext->mEmitData.Clear();
 	ceEmitContext->mEmitData.Clear();
 
 
-	BfCEParseContext ceParseContext = CEEmitParse(typeInstance, activeTypeDef, src);
-		
-	auto typeDeclaration = activeTypeDef->mEmitParser->mAlloc->Alloc<BfTypeDeclaration>();
+	BfCEParseContext ceParseContext = CEEmitParse(typeInstance, src);	
+	auto emitParser = typeInstance->mTypeDef->mSource->ToParser();
+				
+	auto typeDeclaration = emitParser->mAlloc->Alloc<BfTypeDeclaration>();
 
 
 	BfReducer bfReducer;
 	BfReducer bfReducer;
-	bfReducer.mSource = activeTypeDef->mEmitParser;	
+	bfReducer.mSource = emitParser;
 	bfReducer.mPassInstance = mCompiler->mPassInstance;
 	bfReducer.mPassInstance = mCompiler->mPassInstance;
-	bfReducer.mAlloc = activeTypeDef->mEmitParser->mAlloc;
+	bfReducer.mAlloc = emitParser->mAlloc;
 	bfReducer.mSystem = mSystem;
 	bfReducer.mSystem = mSystem;
 	bfReducer.mCurTypeDecl = typeDeclaration;
 	bfReducer.mCurTypeDecl = typeDeclaration;
-	typeDeclaration->mDefineNode = activeTypeDef->mEmitParser->mRootNode;
+	typeDeclaration->mDefineNode = emitParser->mRootNode;
 	bfReducer.HandleTypeDeclaration(typeDeclaration, NULL);
 	bfReducer.HandleTypeDeclaration(typeDeclaration, NULL);
 
 
 	BfDefBuilder defBuilder(mSystem);
 	BfDefBuilder defBuilder(mSystem);
-	defBuilder.mCurSource = activeTypeDef->mEmitParser;
+	defBuilder.mCurSource = emitParser;
 	defBuilder.mCurTypeDef = typeInstance->mTypeDef;
 	defBuilder.mCurTypeDef = typeInstance->mTypeDef;
 	defBuilder.mPassInstance = mCompiler->mPassInstance;
 	defBuilder.mPassInstance = mCompiler->mPassInstance;
 	defBuilder.mIsComptime = true;
 	defBuilder.mIsComptime = true;
 	defBuilder.DoVisitChild(typeDeclaration->mDefineNode);
 	defBuilder.DoVisitChild(typeDeclaration->mDefineNode);
 	defBuilder.FinishTypeDef(typeInstance->mTypeDef->mTypeCode == BfTypeCode_Enum);
 	defBuilder.FinishTypeDef(typeInstance->mTypeDef->mTypeCode == BfTypeCode_Enum);
 
 
+	typeInstance->mTypeDef->ClearOldMemberSets();
+
 	FinishCEParseContext(refNode, typeInstance, &ceParseContext);	
 	FinishCEParseContext(refNode, typeInstance, &ceParseContext);	
 }
 }
 
 
@@ -2106,7 +2133,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
 					ctxStr += TypeToString(typeInstance);
 					ctxStr += TypeToString(typeInstance);
 					ctxStr += " ";
 					ctxStr += " ";
 					ctxStr += customAttribute.mRef->LocationToString();
 					ctxStr += customAttribute.mRef->LocationToString();
-					UpdateCEEmit(ceEmitContext, typeInstance, typeInstance->mTypeDef, ctxStr, customAttribute.mRef);
+					UpdateCEEmit(ceEmitContext, typeInstance, ctxStr, customAttribute.mRef);
 				}
 				}
 			}
 			}
 
 
@@ -2118,17 +2145,17 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
 void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
 void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
 {
 {
 	auto activeTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType;
 	auto activeTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType;
-
+	//auto emitParser = activeTypeDef->mEmitParser;
+			
 	String src;
 	String src;
-	if (activeTypeDef->mEmitParser != NULL)
+	if (mCurTypeInstance->mTypeDef->mEmitParent != NULL)
 		src += "\n\n";
 		src += "\n\n";
 	src += "// Code emission in ";	
 	src += "// Code emission in ";	
 	src += MethodToString(mCurMethodInstance);	
 	src += MethodToString(mCurMethodInstance);	
 	src += "\n";
 	src += "\n";
 	src += code;
 	src += code;
 
 
-	BfReducer bfReducer;
-	bfReducer.mSource = activeTypeDef->mEmitParser;
+	BfReducer bfReducer;	
 	bfReducer.mPassInstance = mCompiler->mPassInstance;
 	bfReducer.mPassInstance = mCompiler->mPassInstance;
 	bfReducer.mSystem = mSystem;
 	bfReducer.mSystem = mSystem;
 	bfReducer.mCurTypeDecl = activeTypeDef->mTypeDeclaration;
 	bfReducer.mCurTypeDecl = activeTypeDef->mTypeDeclaration;
@@ -2140,9 +2167,11 @@ void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
 	bool wantsDIData = (mBfIRBuilder->DbgHasInfo()) && (mHasFullDebugInfo);
 	bool wantsDIData = (mBfIRBuilder->DbgHasInfo()) && (mHasFullDebugInfo);
 	mBfIRBuilder->SaveDebugLocation();
 	mBfIRBuilder->SaveDebugLocation();
 
 
-	BfCEParseContext ceParseContext = CEEmitParse(mCurTypeInstance, activeTypeDef, src);
-	bfReducer.mAlloc = activeTypeDef->mEmitParser->mAlloc;
-	bfReducer.HandleBlock(activeTypeDef->mEmitParser->mRootNode, false);
+	BfCEParseContext ceParseContext = CEEmitParse(mCurTypeInstance, src);
+	auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
+	bfReducer.mSource = emitParser;
+	bfReducer.mAlloc = emitParser->mAlloc;
+	bfReducer.HandleBlock(emitParser->mRootNode, false);
 
 
 	SetAndRestoreValue<BfIRMDNode> prevInlinedAt(mCurMethodState->mCurScope->mDIInlinedAt);
 	SetAndRestoreValue<BfIRMDNode> prevInlinedAt(mCurMethodState->mCurScope->mDIInlinedAt);
 	SetAndRestoreValue<BfIRMDNode> prevDIScope(mCurMethodState->mCurScope->mDIScope);
 	SetAndRestoreValue<BfIRMDNode> prevDIScope(mCurMethodState->mCurScope->mDIScope);
@@ -2161,7 +2190,7 @@ void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
 
 
 		// We used to have the "def" line be the inlining position, but the linker we de-duplicate instances of these functions without regard to their unique line
 		// We used to have the "def" line be the inlining position, but the linker we de-duplicate instances of these functions without regard to their unique line
 		//  definitions, so we need to be consistent and use the actual line
 		//  definitions, so we need to be consistent and use the actual line
-		UpdateSrcPos(activeTypeDef->mEmitParser->mRootNode, BfSrcPosFlag_NoSetDebugLoc);
+		UpdateSrcPos(emitParser->mRootNode, BfSrcPosFlag_NoSetDebugLoc);
 		int defLine = mCurFilePosition.mCurLine;
 		int defLine = mCurFilePosition.mCurLine;
 		auto diParentType = mBfIRBuilder->DbgGetTypeInst(mCurTypeInstance);
 		auto diParentType = mBfIRBuilder->DbgGetTypeInst(mCurTypeInstance);
 		if (!mBfIRBuilder->mIgnoreWrites)
 		if (!mBfIRBuilder->mIgnoreWrites)
@@ -2173,11 +2202,11 @@ void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
 		}
 		}
 	}
 	}
 	
 	
-	UpdateSrcPos(activeTypeDef->mEmitParser->mRootNode);
+	UpdateSrcPos(emitParser->mRootNode);
 
 
 	SetIllegalSrcPos();
 	SetIllegalSrcPos();
 	
 	
-	Visit(activeTypeDef->mEmitParser->mRootNode);
+	Visit(emitParser->mRootNode);
 
 
 	mBfIRBuilder->RestoreDebugLocation();
 	mBfIRBuilder->RestoreDebugLocation();
 	mBfIRBuilder->DupDebugLocation();
 	mBfIRBuilder->DupDebugLocation();
@@ -2309,7 +2338,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance*
 				ctxStr += MethodToString(methodInstance);
 				ctxStr += MethodToString(methodInstance);
 				ctxStr += " ";
 				ctxStr += " ";
 				ctxStr += methodInstance->mMethodDef->GetRefNode()->LocationToString();
 				ctxStr += methodInstance->mMethodDef->GetRefNode()->LocationToString();
-				UpdateCEEmit(ceEmitContext, typeInstance, methodInstance->mMethodDef->mDeclaringType, ctxStr, methodInstance->mMethodDef->GetRefNode());
+				UpdateCEEmit(ceEmitContext, typeInstance, ctxStr, methodInstance->mMethodDef->GetRefNode());
 			}
 			}
 		}
 		}
 
 
@@ -2318,27 +2347,24 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance*
 			DeferRebuildType(typeInstance);
 			DeferRebuildType(typeInstance);
 		}		
 		}		
 	}
 	}
+
+// 	if ((!typeInstance->IsInstanceOf(mCompiler->mValueTypeTypeDef)) &&
+// 		(!typeInstance->IsInstanceOf(mCompiler->mBfObjectTypeDef)) &&
+// 		(!typeInstance->IsBoxed()) &&
+// 		(!typeInstance->IsDelegate()) &&
+// 		(!typeInstance->IsTuple()))
+// 	{
+// 		//zTODO: TESTING, remove!
+// 		CEEmitParse(typeInstance, "// Testing");
+// 	}
 }
 }
 
 
 void BfModule::DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers)
 void BfModule::DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers)
-{
-	typeInstance->mTypeDef->ClearEmitted();
-
-	int startMethodCount = typeInstance->mTypeDef->mMethods.mSize;
-	int startFieldCount = typeInstance->mTypeDef->mFields.mSize;
-	int startPropCount = typeInstance->mTypeDef->mProperties.mSize;
-
+{	
 	CeEmitContext ceEmitContext;
 	CeEmitContext ceEmitContext;
 	ceEmitContext.mType = typeInstance;
 	ceEmitContext.mType = typeInstance;
 	ExecuteCEOnCompile(&ceEmitContext, typeInstance, BfCEOnCompileKind_TypeInit);
 	ExecuteCEOnCompile(&ceEmitContext, typeInstance, BfCEOnCompileKind_TypeInit);
-
-	if ((startMethodCount != typeInstance->mTypeDef->mMethods.mSize) ||
-		(startFieldCount != typeInstance->mTypeDef->mFields.mSize) ||
-		(startPropCount != typeInstance->mTypeDef->mProperties.mSize))
-	{
-		typeInstance->mTypeDef->ClearMemberSets();
-		hadNewMembers = true;
-	}
+	hadNewMembers = (typeInstance->mTypeDef->mEmitParent != NULL);
 }
 }
 
 
 void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
 void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
@@ -2409,8 +2435,13 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
 				src += customAttribute.mRef->LocationToString();
 				src += customAttribute.mRef->LocationToString();
 				src += "\n";
 				src += "\n";
 				
 				
+				//auto emitTypeDef = typeInstance->mCeTypeInfo->mNext->mTypeDef;
+				//auto emitParser = emitTypeDef->mSource->ToParser();
+
+				//auto emitParser = activeTypeDef->mEmitParser;
+
 				BfReducer bfReducer;
 				BfReducer bfReducer;
-				bfReducer.mSource = activeTypeDef->mEmitParser;
+				//bfReducer.mSource = emitParser;
 				bfReducer.mPassInstance = mCompiler->mPassInstance;				
 				bfReducer.mPassInstance = mCompiler->mPassInstance;				
 				bfReducer.mSystem = mSystem;
 				bfReducer.mSystem = mSystem;
 				bfReducer.mCurTypeDecl = activeTypeDef->mTypeDeclaration;
 				bfReducer.mCurTypeDecl = activeTypeDef->mTypeDeclaration;
@@ -2421,28 +2452,32 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
 					SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, customAttribute.mRef);
 					SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, customAttribute.mRef);
 
 
 					String entrySrc = src;
 					String entrySrc = src;
-					if (activeTypeDef->mEmitParser != NULL)
+					if (mCurTypeInstance->mTypeDef->mEmitParent != NULL)
 						entrySrc += "\n\n";
 						entrySrc += "\n\n";
 					entrySrc += src;
 					entrySrc += src;
 					entrySrc += ceEmitContext.mEmitData;
 					entrySrc += ceEmitContext.mEmitData;
-					BfCEParseContext ceParseContext = CEEmitParse(typeInstance, activeTypeDef, entrySrc);
-					bfReducer.mAlloc = activeTypeDef->mEmitParser->mAlloc;
-					bfReducer.HandleBlock(activeTypeDef->mEmitParser->mRootNode, false);
-					Visit(activeTypeDef->mEmitParser->mRootNode);
+					BfCEParseContext ceParseContext = CEEmitParse(typeInstance, entrySrc);
+					auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
+					bfReducer.mSource = emitParser;
+					bfReducer.mAlloc = emitParser->mAlloc;
+					bfReducer.HandleBlock(emitParser->mRootNode, false);
+					Visit(emitParser->mRootNode);
 					FinishCEParseContext(customAttribute.mRef, typeInstance, &ceParseContext);
 					FinishCEParseContext(customAttribute.mRef, typeInstance, &ceParseContext);
 				}
 				}
 
 
 				if (!ceEmitContext.mExitEmitData.IsEmpty())
 				if (!ceEmitContext.mExitEmitData.IsEmpty())
 				{
 				{
 					String exitSrc;
 					String exitSrc;
-					if (activeTypeDef->mEmitParser != NULL)
+					if (mCurTypeInstance->mTypeDef->mEmitParent != NULL)
 						exitSrc += "\n\n";
 						exitSrc += "\n\n";
 					exitSrc += src;
 					exitSrc += src;
 					exitSrc += ceEmitContext.mExitEmitData;
 					exitSrc += ceEmitContext.mExitEmitData;
-					BfCEParseContext ceParseContext = CEEmitParse(typeInstance, activeTypeDef, exitSrc);
-					bfReducer.mAlloc = activeTypeDef->mEmitParser->mAlloc;
-					bfReducer.HandleBlock(activeTypeDef->mEmitParser->mRootNode, false);
-					auto deferredBlock = AddDeferredBlock(activeTypeDef->mEmitParser->mRootNode, &mCurMethodState->mHeadScope);
+					BfCEParseContext ceParseContext = CEEmitParse(typeInstance, exitSrc);
+					auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
+					bfReducer.mSource = emitParser;
+					bfReducer.mAlloc = emitParser->mAlloc;
+					bfReducer.HandleBlock(emitParser->mRootNode, false);
+					auto deferredBlock = AddDeferredBlock(emitParser->mRootNode, &mCurMethodState->mHeadScope);
 					deferredBlock->mEmitRefNode = customAttribute.mRef;
 					deferredBlock->mEmitRefNode = customAttribute.mRef;
 					FinishCEParseContext(customAttribute.mRef, typeInstance, &ceParseContext);
 					FinishCEParseContext(customAttribute.mRef, typeInstance, &ceParseContext);
 				}
 				}
@@ -2617,7 +2652,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 		resolvedTypeRef->mSize = typeInstance->mAlign = mSystem->mPtrSize;
 		resolvedTypeRef->mSize = typeInstance->mAlign = mSystem->mPtrSize;
 	}
 	}
 	
 	
-	BF_ASSERT((typeInstance->mMethodInstanceGroups.size() == 0) || (typeInstance->mMethodInstanceGroups.size() == typeDef->mMethods.size()) || (typeInstance->mTypeDef->mHasEmitMembers));
+	BF_ASSERT((typeInstance->mMethodInstanceGroups.size() == 0) || (typeInstance->mMethodInstanceGroups.size() == typeDef->mMethods.size()) || (typeInstance->mCeTypeInfo != NULL));
 	typeInstance->mMethodInstanceGroups.Resize(typeDef->mMethods.size());
 	typeInstance->mMethodInstanceGroups.Resize(typeDef->mMethods.size());
 	for (int i = 0; i < (int)typeInstance->mMethodInstanceGroups.size(); i++)
 	for (int i = 0; i < (int)typeInstance->mMethodInstanceGroups.size(); i++)
 	{
 	{
@@ -3111,7 +3146,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 						BfInterfaceDecl ifaceDecl;
 						BfInterfaceDecl ifaceDecl;
 						ifaceDecl.mIFaceTypeInst = ifaceInst;
 						ifaceDecl.mIFaceTypeInst = ifaceInst;
 						ifaceDecl.mTypeRef = checkTypeRef;
 						ifaceDecl.mTypeRef = checkTypeRef;
-						ifaceDecl.mDeclaringType = typeDef;
+						ifaceDecl.mDeclaringType = typeDef->GetDefinition();
 						interfaces.push_back(ifaceDecl);
 						interfaces.push_back(ifaceDecl);
 					}
 					}
 					else
 					else
@@ -3378,8 +3413,8 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 			typeInterfaceInst.mStartInterfaceTableIdx = -1;
 			typeInterfaceInst.mStartInterfaceTableIdx = -1;
 			typeInterfaceInst.mStartVirtualIdx = -1;
 			typeInterfaceInst.mStartVirtualIdx = -1;
 			typeInterfaceInst.mIsRedeclared = false;
 			typeInterfaceInst.mIsRedeclared = false;
-			typeInstance->mInterfaces.push_back(typeInterfaceInst);
-			
+			typeInstance->mInterfaces.push_back(typeInterfaceInst);			
+
 			AddDependency(checkInterface, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface);
 			AddDependency(checkInterface, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface);
 
 
 			// Interfaces can list other interfaces in their declaration, so pull those in too
 			// Interfaces can list other interfaces in their declaration, so pull those in too
@@ -3892,8 +3927,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 			}
 			}
 
 
 			if (hadNewMembers)
 			if (hadNewMembers)
-			{
-				typeInstance->mTypeDef->mHasEmitMembers = true;
+			{				
 				DoPopulateType(resolvedTypeRef, populateType);
 				DoPopulateType(resolvedTypeRef, populateType);
 				return;
 				return;
 			}
 			}
@@ -5365,7 +5399,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
 
 
 						for (auto& attrAttr : attrCustomAttributes->mAttributes)
 						for (auto& attrAttr : attrCustomAttributes->mAttributes)
 						{
 						{
-							if (attrAttr.mType->ToTypeInstance()->mTypeDef == mCompiler->mAttributeUsageAttributeTypeDef)
+							if (attrAttr.mType->ToTypeInstance()->IsInstanceOf(mCompiler->mAttributeUsageAttributeTypeDef))
 							{
 							{
 								// Check for Flags arg
 								// Check for Flags arg
 								if (attrAttr.mCtorArgs.size() < 2)
 								if (attrAttr.mCtorArgs.size() < 2)
@@ -5478,6 +5512,16 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
 						}
 						}
 						else
 						else
 						{
 						{
+							auto matchedMethodDef = matchedMethod->mMethodDef;
+							if (matchedMethodDef->mDeclaringType->IsEmitted())
+							{
+								Fail("Boxed interface binding error to emitted method", mCurTypeInstance->mTypeDef->GetRefNode());
+								continue;
+							}
+
+							if (underlyingTypeInstance->mTypeDef->IsEmitted())
+								matchedMethodDef = underlyingTypeInstance->mTypeDef->mEmitParent->mMethods[matchedMethodDef->mIdx];
+
 							if (!matchedMethod->mIsForeignMethodDef)
 							if (!matchedMethod->mIsForeignMethodDef)
 							{
 							{
 								BfMethodInstanceGroup* boxedMethodInstanceGroup = &typeInstance->mMethodInstanceGroups[matchedMethod->mMethodDef->mIdx];
 								BfMethodInstanceGroup* boxedMethodInstanceGroup = &typeInstance->mMethodInstanceGroups[matchedMethod->mMethodDef->mIdx];
@@ -5491,7 +5535,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
 							auto methodFlags = matchedMethod->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None;
 							auto methodFlags = matchedMethod->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None;
 							methodFlags = (BfGetMethodInstanceFlags)(methodFlags | BfGetMethodInstanceFlag_MethodInstanceOnly);
 							methodFlags = (BfGetMethodInstanceFlags)(methodFlags | BfGetMethodInstanceFlag_MethodInstanceOnly);
 							
 							
-							auto moduleMethodInstance = GetMethodInstance(typeInstance, matchedMethod->mMethodDef, BfTypeVector(),
+							auto moduleMethodInstance = GetMethodInstance(typeInstance, matchedMethodDef, BfTypeVector(),
 								methodFlags,
 								methodFlags,
 								matchedMethod->GetForeignType());
 								matchedMethod->GetForeignType());
 							auto methodInstance = moduleMethodInstance.mMethodInstance;
 							auto methodInstance = moduleMethodInstance.mMethodInstance;
@@ -6131,7 +6175,10 @@ BfArrayType* BfModule::CreateArrayType(BfType* resolvedType, int dimensions)
 	arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(resolvedType);
 	arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(resolvedType);
 	auto resolvedArrayType = ResolveType(arrayType);
 	auto resolvedArrayType = ResolveType(arrayType);
 	if (resolvedArrayType != arrayType)
 	if (resolvedArrayType != arrayType)
+	{
+		arrayType->Dispose();
 		mContext->mArrayTypePool.GiveBack(arrayType);
 		mContext->mArrayTypePool.GiveBack(arrayType);
+	}
 	return (BfArrayType*)resolvedArrayType;
 	return (BfArrayType*)resolvedArrayType;
 }
 }
 
 
@@ -6693,13 +6740,16 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef, bool allowCreate
 	boxedType->mContext = mContext;
 	boxedType->mContext = mContext;
 	boxedType->mElementType = resolvedTypeRef;
 	boxedType->mElementType = resolvedTypeRef;
 	if (typeInst != NULL)
 	if (typeInst != NULL)
-		boxedType->mTypeDef = typeInst->mTypeDef;
+		boxedType->mTypeDef = typeInst->mTypeDef->GetDefinition();
 	else
 	else
 		boxedType->mTypeDef = mCompiler->mValueTypeTypeDef;
 		boxedType->mTypeDef = mCompiler->mValueTypeTypeDef;
 	boxedType->mBoxedFlags = isStructPtr ? BfBoxedType::BoxedFlags_StructPtr : BfBoxedType::BoxedFlags_None;
 	boxedType->mBoxedFlags = isStructPtr ? BfBoxedType::BoxedFlags_StructPtr : BfBoxedType::BoxedFlags_None;
 	auto resolvedBoxedType = ResolveType(boxedType, populateType, resolveFlags);
 	auto resolvedBoxedType = ResolveType(boxedType, populateType, resolveFlags);
 	if (resolvedBoxedType != boxedType)
 	if (resolvedBoxedType != boxedType)
+	{
+		boxedType->Dispose();
 		mContext->mBoxedTypePool.GiveBack(boxedType);
 		mContext->mBoxedTypePool.GiveBack(boxedType);
+	}
 	return (BfBoxedType*)resolvedBoxedType;
 	return (BfBoxedType*)resolvedBoxedType;
 }
 }
 
 
@@ -6753,6 +6803,7 @@ BfTypeInstance* BfModule::CreateTupleType(const BfTypeVector& fieldTypes, const
 	if (resolvedTupleType != tupleType)
 	if (resolvedTupleType != tupleType)
 	{
 	{
 		BF_ASSERT(tupleType->mContext != NULL);
 		BF_ASSERT(tupleType->mContext != NULL);
+		tupleType->Dispose();
 		mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType);
 		mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType);
 	}
 	}
 	
 	
@@ -6814,7 +6865,7 @@ BfModifiedTypeType* BfModule::CreateModifiedTypeType(BfType* resolvedTypeRef, Bf
 	retTypeType->mContext = mContext;
 	retTypeType->mContext = mContext;
 	retTypeType->mModifiedKind = modifiedKind;
 	retTypeType->mModifiedKind = modifiedKind;
 	retTypeType->mElementType = resolvedTypeRef;
 	retTypeType->mElementType = resolvedTypeRef;
-	auto resolvedRetTypeType = ResolveType(retTypeType);
+	auto resolvedRetTypeType = ResolveType(retTypeType);	
 	if (resolvedRetTypeType != retTypeType)
 	if (resolvedRetTypeType != retTypeType)
 		mContext->mModifiedTypeTypePool.GiveBack(retTypeType);
 		mContext->mModifiedTypeTypePool.GiveBack(retTypeType);
 	return (BfModifiedTypeType*)resolvedRetTypeType;
 	return (BfModifiedTypeType*)resolvedRetTypeType;
@@ -6841,6 +6892,8 @@ BfPointerType* BfModule::CreatePointerType(BfTypeReference* typeRef)
 
 
 BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
 BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
 {
 {
+	BF_ASSERT(typeDef->mDefState != BfTypeDef::DefState_Emitted);
+
 	if (typeDef->mTypeDeclaration == NULL)
 	if (typeDef->mTypeDeclaration == NULL)
 	{
 	{
 		BF_ASSERT(!typeDef->mIsDelegate && !typeDef->mIsFunction);
 		BF_ASSERT(!typeDef->mIsDelegate && !typeDef->mIsFunction);
@@ -7159,7 +7212,7 @@ bool BfModule::IsInnerType(BfTypeDef* checkInnerType, BfTypeDef* checkOuterType)
 			return false;
 			return false;
 		if (outerType->mIsPartial)
 		if (outerType->mIsPartial)
 			outerType = mSystem->GetCombinedPartial(outerType);
 			outerType = mSystem->GetCombinedPartial(outerType);
-		if (outerType == checkOuterType)
+		if (outerType->GetDefinition() == checkOuterType->GetDefinition())
 			return true;
 			return true;
 		checkInnerType = checkInnerType->mOuterType;
 		checkInnerType = checkInnerType->mOuterType;
 	}	
 	}	
@@ -7167,6 +7220,8 @@ bool BfModule::IsInnerType(BfTypeDef* checkInnerType, BfTypeDef* checkOuterType)
 
 
 BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& genericArgs, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
 BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& genericArgs, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
 {
 {
+	BF_ASSERT(typeDef->mDefState != BfTypeDef::DefState_Emitted);
+
 	if (typeDef->mGenericParamDefs.size() == 0)
 	if (typeDef->mGenericParamDefs.size() == 0)
 		return ResolveTypeDef(typeDef, populateType, resolveFlags);
 		return ResolveTypeDef(typeDef, populateType, resolveFlags);
 
 
@@ -7206,6 +7261,7 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& generic
 		{
 		{
 			delete arrayInstType->mGenericTypeInfo;
 			delete arrayInstType->mGenericTypeInfo;
 			arrayInstType->mGenericTypeInfo = NULL;
 			arrayInstType->mGenericTypeInfo = NULL;
+			arrayInstType->Dispose();
 			mContext->mArrayTypeInstancePool.GiveBack(arrayInstType);
 			mContext->mArrayTypeInstancePool.GiveBack(arrayInstType);
 			mContext->mTypeDefTypeRefPool.GiveBack(typeRef);
 			mContext->mTypeDefTypeRefPool.GiveBack(typeRef);
 		}
 		}
@@ -7250,29 +7306,7 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& generic
 	BfType* resolvedType = NULL;
 	BfType* resolvedType = NULL;
 
 
 	bool failed = false;
 	bool failed = false;
-// 	if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
-// 	{
-// 		auto aliasType = (BfGenericTypeAliasType*)genericInstType;
-// 		aliasType->mAliasToType = NULL;
-// 		auto typeAliasDecl = (BfTypeAliasDeclaration*)typeDef->mTypeDeclaration;
-// 		SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, aliasType);
-// 		SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
-//  		BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState);
-// 		typeState.mCurTypeDef = typeDef; 		
-//  		SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
-// 		if (typeAliasDecl->mAliasToType != NULL)			
-// 			aliasType->mAliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType);			
-// 
-// 		resolvedType = ResolveType(genericInstType, BfPopulateType_IdentityNoRemapAlias);
-// 		if ((resolvedType != NULL) && (populateType >= BfPopulateType_Declaration))
-// 			PopulateType(resolvedType, populateType);
-// 	}
-// 	else
-	{
-		resolvedType = ResolveType(genericInstType, populateType, resolveFlags);
-	}
-	
-	
+	resolvedType = ResolveType(genericInstType, populateType, resolveFlags);	
 	if (resolvedType != genericInstType)
 	if (resolvedType != genericInstType)
 	{		
 	{		
 		BF_ASSERT(genericInstType->mGenericTypeInfo->mGenericParams.size() == 0);
 		BF_ASSERT(genericInstType->mGenericTypeInfo->mGenericParams.size() == 0);
@@ -7283,7 +7317,10 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& generic
 		if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
 		if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
 			mContext->mAliasTypePool.GiveBack((BfTypeAliasType*)genericInstType);
 			mContext->mAliasTypePool.GiveBack((BfTypeAliasType*)genericInstType);
 		else
 		else
+		{
+			genericInstType->Dispose();
 			mContext->mGenericTypeInstancePool.GiveBack(genericInstType);
 			mContext->mGenericTypeInstancePool.GiveBack(genericInstType);
+		}
 		mContext->mTypeDefTypeRefPool.GiveBack(typeRef);
 		mContext->mTypeDefTypeRefPool.GiveBack(typeRef);
 	}
 	}
 	BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
 	BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
@@ -7302,19 +7339,18 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic
 
 
 	BfTypeDef* curTypeDef = NULL;
 	BfTypeDef* curTypeDef = NULL;
 	if (mCurTypeInstance != NULL)
 	if (mCurTypeInstance != NULL)
-		curTypeDef = mCurTypeInstance->mTypeDef;
+		curTypeDef = mCurTypeInstance->mTypeDef->GetDefinition();
 
 
 	if (auto directTypeDef = BfNodeDynCast<BfDirectTypeReference>(typeRef))
 	if (auto directTypeDef = BfNodeDynCast<BfDirectTypeReference>(typeRef))
 	{
 	{
 		auto typeInst = directTypeDef->mType->ToTypeInstance();
 		auto typeInst = directTypeDef->mType->ToTypeInstance();
-		return typeInst->mTypeDef;
+		return typeInst->mTypeDef->GetDefinition();
 	}
 	}
 
 
 	auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef);
 	auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef);
 	auto directStrTypeDef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
 	auto directStrTypeDef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
 	if ((namedTypeRef != NULL) || (directStrTypeDef != NULL))
 	if ((namedTypeRef != NULL) || (directStrTypeDef != NULL))
-	{
-		
+	{		
 		BfTypeLookupError error;
 		BfTypeLookupError error;
 		error.mRefNode = typeRef;
 		error.mRefNode = typeRef;
 		BfTypeDef* typeDef = FindTypeDef(typeRef, NULL, &error, numGenericParams);		
 		BfTypeDef* typeDef = FindTypeDef(typeRef, NULL, &error, numGenericParams);		
@@ -7392,7 +7428,7 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic
 			*outType = type;
 			*outType = type;
 		auto typeInst = type->ToTypeInstance();
 		auto typeInst = type->ToTypeInstance();
 		if (typeInst != NULL)
 		if (typeInst != NULL)
-			return typeInst->mTypeDef;
+			return typeInst->mTypeDef->GetDefinition();
 	}
 	}
 
 
 	if ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0)
 	if ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0)
@@ -7631,6 +7667,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
 		{
 		{
 			delete tupleType->mGenericTypeInfo;
 			delete tupleType->mGenericTypeInfo;
 			tupleType->mGenericTypeInfo = NULL;			
 			tupleType->mGenericTypeInfo = NULL;			
+			tupleType->Dispose();
 			mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType);
 			mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType);
 		}
 		}
 		BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
 		BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
@@ -7828,9 +7865,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
 				AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);			
 				AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);			
 		}
 		}
 		else
 		else
-		{			
-			delete delegateType->mGenericTypeInfo;
-			delegateType->mGenericTypeInfo = NULL;
+		{						
+			delegateType->Dispose();
 			mContext->mDelegateTypePool.GiveBack((BfDelegateType*)delegateType);			
 			mContext->mDelegateTypePool.GiveBack((BfDelegateType*)delegateType);			
 		}
 		}
 		BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
 		BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
@@ -7857,7 +7893,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
 				genericArgs.push_back(genericArg);
 				genericArgs.push_back(genericArg);
 		}
 		}
 
 
-		auto resolvedType = ResolveTypeDef(genericTypeInst->mTypeDef, genericArgs, BfPopulateType_BaseType);
+		auto resolvedType = ResolveTypeDef(genericTypeInst->mTypeDef->GetDefinition(), genericArgs, BfPopulateType_BaseType);
 		BfTypeInstance* specializedType = NULL;
 		BfTypeInstance* specializedType = NULL;
 		if (resolvedType != NULL)
 		if (resolvedType != NULL)
 			specializedType = resolvedType->ToGenericTypeInstance();
 			specializedType = resolvedType->ToGenericTypeInstance();
@@ -8470,7 +8506,7 @@ BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool
 	if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mForceActiveTypeDef != NULL))
 	if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mForceActiveTypeDef != NULL))
 		return mContext->mCurTypeState->mForceActiveTypeDef;
 		return mContext->mCurTypeState->mForceActiveTypeDef;
 	if (typeInstance != NULL)
 	if (typeInstance != NULL)
-		useTypeDef = typeInstance->mTypeDef;
+		useTypeDef = typeInstance->mTypeDef->GetDefinition();
 	if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL) && (useMixinDecl))
 	if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL) && (useMixinDecl))
 		useTypeDef = mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType;
 		useTypeDef = mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType;
 	else if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mDeclaringType != NULL))
 	else if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mDeclaringType != NULL))
@@ -9253,46 +9289,6 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
 			BfGenericParamDef* genericParamDef = NULL;
 			BfGenericParamDef* genericParamDef = NULL;
 			BfType* genericParamResult = NULL;
 			BfType* genericParamResult = NULL;
 			bool disallowConstExprValue = false;
 			bool disallowConstExprValue = false;
-			if ((genericCheckTypeInstance != NULL) && (genericCheckTypeInstance->IsGenericTypeInstance()))
-			{
-				auto genericTypeInst = (BfTypeInstance*)genericCheckTypeInstance;
-				auto* genericParams = &curTypeDef->mGenericParamDefs;
-
-				if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
-				{
-					auto activeTypeDef = GetActiveTypeDef(NULL, true);
-					genericParams = &activeTypeDef->mGenericParamDefs;
-				}
-
-				for (int genericParamIdx = (int)genericParams->size() - 1; genericParamIdx >= 0; genericParamIdx--)
-				{
-					auto checkGenericParamDef = (*genericParams)[genericParamIdx];
-					String genericName = checkGenericParamDef->mName;
-					if (genericName == findName)
-					{
-						genericParamDef = checkGenericParamDef;
-						if (((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0) &&
-							((resolveFlags & BfResolveTypeRefFlag_AllowGenericTypeParamConstValue) == 0))
-							disallowConstExprValue = true;
-
-						HandleTypeGenericParamRef(typeRef, curTypeDef, genericParamIdx);
-
-						if ((resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0)
-							return GetGenericParamType(BfGenericParamKind_Type, genericParamIdx);
-						else
-						{
-							SetAndRestoreValue<BfGetSymbolReferenceKind> prevSymbolRefKind;
-							if (mCompiler->mResolvePassData != NULL) // Don't add these typeRefs, they are indirect
-								prevSymbolRefKind.Init(mCompiler->mResolvePassData->mGetSymbolReferenceKind, BfGetSymbolReferenceKind_None);							
-							genericParamResult = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[genericParamIdx];
-							if ((genericParamResult != NULL) &&
-								(genericParamResult->IsConstExprValue()) &&
-								((resolveFlags & BfResolveTypeRefFlag_AllowGenericTypeParamConstValue) == 0))
-								disallowConstExprValue = true;
-						}
-					}
-				}
-			}
 
 
 			if ((contextMethodInstance != NULL) && (genericParamResult == NULL))
 			if ((contextMethodInstance != NULL) && (genericParamResult == NULL))
 			{
 			{
@@ -9318,7 +9314,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
 					auto checkGenericParamDef = checkMethodInstance->mMethodDef->mGenericParams[genericParamIdx];
 					auto checkGenericParamDef = checkMethodInstance->mMethodDef->mGenericParams[genericParamIdx];
 					String genericName = checkGenericParamDef->mName;
 					String genericName = checkGenericParamDef->mName;
 					if (genericName == findName)
 					if (genericName == findName)
-					{						
+					{
 						genericParamDef = checkGenericParamDef;
 						genericParamDef = checkGenericParamDef;
 						if (((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0) &&
 						if (((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0) &&
 							((resolveFlags & BfResolveTypeRefFlag_AllowGenericMethodParamConstValue) == 0))
 							((resolveFlags & BfResolveTypeRefFlag_AllowGenericMethodParamConstValue) == 0))
@@ -9330,7 +9326,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
 							return GetGenericParamType(BfGenericParamKind_Method, genericParamIdx);
 							return GetGenericParamType(BfGenericParamKind_Method, genericParamIdx);
 						else
 						else
 						{
 						{
-							if ((mContext->mCurConstraintState != NULL) && (mContext->mCurConstraintState->mMethodInstance == checkMethodInstance) && 
+							if ((mContext->mCurConstraintState != NULL) && (mContext->mCurConstraintState->mMethodInstance == checkMethodInstance) &&
 								(mContext->mCurConstraintState->mMethodGenericArgsOverride != NULL))
 								(mContext->mCurConstraintState->mMethodGenericArgsOverride != NULL))
 							{
 							{
 								return ResolveTypeResult(typeRef, (*mContext->mCurConstraintState->mMethodGenericArgsOverride)[genericParamIdx], populateType, resolveFlags);
 								return ResolveTypeResult(typeRef, (*mContext->mCurConstraintState->mMethodGenericArgsOverride)[genericParamIdx], populateType, resolveFlags);
@@ -9348,6 +9344,47 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
 					}
 					}
 				}
 				}
 			}
 			}
+			
+			if ((genericCheckTypeInstance != NULL) && (genericCheckTypeInstance->IsGenericTypeInstance()) && (genericParamResult == NULL))
+			{
+				auto genericTypeInst = (BfTypeInstance*)genericCheckTypeInstance;
+				auto* genericParams = &curTypeDef->mGenericParamDefs;
+
+				if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
+				{
+					auto activeTypeDef = GetActiveTypeDef(NULL, true);
+					genericParams = &activeTypeDef->mGenericParamDefs;
+				}
+
+				for (int genericParamIdx = (int)genericParams->size() - 1; genericParamIdx >= 0; genericParamIdx--)
+				{
+					auto checkGenericParamDef = (*genericParams)[genericParamIdx];
+					String genericName = checkGenericParamDef->mName;
+					if (genericName == findName)
+					{
+						genericParamDef = checkGenericParamDef;
+						if (((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0) &&
+							((resolveFlags & BfResolveTypeRefFlag_AllowGenericTypeParamConstValue) == 0))
+							disallowConstExprValue = true;
+
+						HandleTypeGenericParamRef(typeRef, curTypeDef, genericParamIdx);
+
+						if ((resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0)
+							return GetGenericParamType(BfGenericParamKind_Type, genericParamIdx);
+						else
+						{
+							SetAndRestoreValue<BfGetSymbolReferenceKind> prevSymbolRefKind;
+							if (mCompiler->mResolvePassData != NULL) // Don't add these typeRefs, they are indirect
+								prevSymbolRefKind.Init(mCompiler->mResolvePassData->mGetSymbolReferenceKind, BfGetSymbolReferenceKind_None);							
+							genericParamResult = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[genericParamIdx];
+							if ((genericParamResult != NULL) &&
+								(genericParamResult->IsConstExprValue()) &&
+								((resolveFlags & BfResolveTypeRefFlag_AllowGenericTypeParamConstValue) == 0))
+								disallowConstExprValue = true;
+						}
+					}
+				}
+			}			
 
 
 			if (genericParamResult != NULL)
 			if (genericParamResult != NULL)
 			{
 			{
@@ -9670,9 +9707,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
 									resolvedType = GetDelegateReturnType(genericParamInstance->mTypeConstraint);
 									resolvedType = GetDelegateReturnType(genericParamInstance->mTypeConstraint);
 									return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
 									return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
 								}
 								}
-								else if ((genericParamInstance->mTypeConstraint->IsTypeInstance()) &&
-									((genericParamInstance->mTypeConstraint->ToTypeInstance()->mTypeDef == mCompiler->mDelegateTypeDef) ||
-									(genericParamInstance->mTypeConstraint->ToTypeInstance()->mTypeDef == mCompiler->mFunctionTypeDef)))
+								else if ((genericParamInstance->mTypeConstraint->IsInstanceOf(mCompiler->mDelegateTypeDef)) ||
+									(genericParamInstance->mTypeConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)))
 								{
 								{
 									allowThrough = true;
 									allowThrough = true;
 								}
 								}
@@ -9796,6 +9832,13 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
 		}
 		}
 	}
 	}
 
 
+	static int sCallIdx = 0;	
+	int callIdx = sCallIdx++;
+	if (callIdx == 0x00006CA4)
+	{
+		NOP;
+	}
+
 	BfResolvedTypeSet::LookupContext lookupCtx;
 	BfResolvedTypeSet::LookupContext lookupCtx;
 	lookupCtx.mResolveFlags = (BfResolveTypeRefFlags)(resolveFlags & (BfResolveTypeRefFlag_NoCreate | BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_DisallowComptime | BfResolveTypeRefFlag_AllowInferredSizedArray));
 	lookupCtx.mResolveFlags = (BfResolveTypeRefFlags)(resolveFlags & (BfResolveTypeRefFlag_NoCreate | BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_DisallowComptime | BfResolveTypeRefFlag_AllowInferredSizedArray));
 	lookupCtx.mRootTypeRef = typeRef;
 	lookupCtx.mRootTypeRef = typeRef;
@@ -10829,7 +10872,7 @@ BfTypeInstance* BfModule::GetUnspecializedTypeInstance(BfTypeInstance* typeInst)
 	BF_ASSERT((!typeInst->IsDelegateFromTypeRef()) && (!typeInst->IsFunctionFromTypeRef()));
 	BF_ASSERT((!typeInst->IsDelegateFromTypeRef()) && (!typeInst->IsFunctionFromTypeRef()));
 
 
 	auto genericTypeInst = (BfTypeInstance*)typeInst;
 	auto genericTypeInst = (BfTypeInstance*)typeInst;
-	auto result = ResolveTypeDef(genericTypeInst->mTypeDef, BfPopulateType_Declaration);
+	auto result = ResolveTypeDef(genericTypeInst->mTypeDef->GetDefinition(), BfPopulateType_Declaration);
 	BF_ASSERT((result != NULL) && (result->IsUnspecializedType()));
 	BF_ASSERT((result != NULL) && (result->IsUnspecializedType()));
 	if (result == NULL)
 	if (result == NULL)
 		return NULL;
 		return NULL;
@@ -11266,7 +11309,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
 				{
 				{
 					SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
 					SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
 					auto constraintTypeInst = genericParamInst->mTypeConstraint->ToTypeInstance();
 					auto constraintTypeInst = genericParamInst->mTypeConstraint->ToTypeInstance();
-					if ((constraintTypeInst != NULL) && (constraintTypeInst->mTypeDef == mCompiler->mEnumTypeDef) && (explicitCast))
+					if ((constraintTypeInst != NULL) && (constraintTypeInst->IsInstanceOf(mCompiler->mEnumTypeDef)) && (explicitCast))
 					{
 					{
 						// Enum->int
 						// Enum->int
 						if ((explicitCast) && (toType->IsInteger()))
 						if ((explicitCast) && (toType->IsInteger()))
@@ -12981,7 +13024,7 @@ bool BfModule::TypeHasParentOrEquals(BfTypeDef* checkChildTypeDef, BfTypeDef* ch
 	while (checkType->mNestDepth > checkParentTypeDef->mNestDepth)
 	while (checkType->mNestDepth > checkParentTypeDef->mNestDepth)
 		checkType = checkType->mOuterType;
 		checkType = checkType->mOuterType;
 
 
-	if (checkType == checkParentTypeDef)
+	if (checkType->GetDefinition() == checkParentTypeDef->GetDefinition())
 		return true;
 		return true;
 	if (checkType->mNameEx != checkParentTypeDef->mNameEx)
 	if (checkType->mNameEx != checkParentTypeDef->mNameEx)
 		return false;
 		return false;
@@ -13000,7 +13043,7 @@ BfTypeDef* BfModule::FindCommonOuterType(BfTypeDef* type, BfTypeDef* type2)
 {
 {
 	if ((type == NULL) || (type2 == NULL))
 	if ((type == NULL) || (type2 == NULL))
 		return NULL;
 		return NULL;
-	int curNestDepth = std::min(type->mNestDepth, type2->mNestDepth);
+	int curNestDepth = BF_MIN(type->mNestDepth, type2->mNestDepth);
 	while (type->mNestDepth > curNestDepth)
 	while (type->mNestDepth > curNestDepth)
 		type = type->mOuterType;
 		type = type->mOuterType;
 	while (type2->mNestDepth > curNestDepth)
 	while (type2->mNestDepth > curNestDepth)
@@ -13010,7 +13053,7 @@ BfTypeDef* BfModule::FindCommonOuterType(BfTypeDef* type, BfTypeDef* type2)
 	{
 	{
 		if ((!type->mIsPartial) && (!type2->mIsPartial))
 		if ((!type->mIsPartial) && (!type2->mIsPartial))
 		{
 		{
-			if (type == type2)
+			if (type->GetDefinition() == type2->GetDefinition())
 				return type;
 				return type;
 		}
 		}
 		else
 		else

+ 14 - 8
IDEHelper/Compiler/BfResolvePass.cpp

@@ -55,44 +55,50 @@ void BfResolvePassData::RecordReplaceNode(BfAstNode* node)
 }
 }
 
 
 void BfResolvePassData::HandleMethodReference(BfAstNode* node, BfTypeDef* typeDef, BfMethodDef* methodDef)
 void BfResolvePassData::HandleMethodReference(BfAstNode* node, BfTypeDef* typeDef, BfMethodDef* methodDef)
-{	
-	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Method) && (mSymbolReferenceTypeDef == typeDef) && (mSymbolReferenceMethodIdx == methodDef->mIdx))	
+{
+	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Method) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && 
+		(mSymbolReferenceMethodIdx == methodDef->mIdx) && (!methodDef->mDeclaringType->IsEmitted()))
 		RecordReplaceNode(node);
 		RecordReplaceNode(node);
 }
 }
 
 
 void BfResolvePassData::HandleFieldReference(BfAstNode* node, BfTypeDef* typeDef, BfFieldDef* fieldDef)
 void BfResolvePassData::HandleFieldReference(BfAstNode* node, BfTypeDef* typeDef, BfFieldDef* fieldDef)
 {
 {
-	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field) && (mSymbolReferenceTypeDef == typeDef) && (mSymbolReferenceFieldIdx == fieldDef->mIdx))
+	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && 
+		(mSymbolReferenceFieldIdx == fieldDef->mIdx) && (!fieldDef->mDeclaringType->IsEmitted()))
 		RecordReplaceNode(node);
 		RecordReplaceNode(node);
 }
 }
 
 
 void BfResolvePassData::HandlePropertyReference(BfAstNode* node, BfTypeDef* typeDef, BfPropertyDef* propDef)
 void BfResolvePassData::HandlePropertyReference(BfAstNode* node, BfTypeDef* typeDef, BfPropertyDef* propDef)
 {
 {
-	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Property) && (mSymbolReferenceTypeDef == typeDef) && (mSymbolReferencePropertyIdx == propDef->mIdx))
+	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Property) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && 
+		(mSymbolReferencePropertyIdx == propDef->mIdx) && (!propDef->mDeclaringType->IsEmitted()))
 		RecordReplaceNode(node);
 		RecordReplaceNode(node);
 }
 }
 
 
 void BfResolvePassData::HandleLocalReference(BfIdentifierNode* identifier, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx)
 void BfResolvePassData::HandleLocalReference(BfIdentifierNode* identifier, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx)
 {
 {
-	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Local) && (mSymbolReferenceTypeDef == typeDef) && (mSymbolReferenceMethodIdx == methodDef->mIdx) && (localVarIdx == mSymbolReferenceLocalIdx))
+	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Local) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && 
+		(mSymbolReferenceMethodIdx == methodDef->mIdx) && (localVarIdx == mSymbolReferenceLocalIdx) && (!methodDef->mDeclaringType->IsEmitted()))
 		RecordReplaceNode(identifier);
 		RecordReplaceNode(identifier);
 }
 }
 
 
 void BfResolvePassData::HandleTypeGenericParam(BfAstNode* node, BfTypeDef* typeDef, int genericParamIdx)
 void BfResolvePassData::HandleTypeGenericParam(BfAstNode* node, BfTypeDef* typeDef, int genericParamIdx)
 {
 {
-	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_TypeGenericParam) && (mSymbolReferenceTypeDef == typeDef) && (genericParamIdx == mSymbolTypeGenericParamIdx))
+	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_TypeGenericParam) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && (genericParamIdx == mSymbolTypeGenericParamIdx))
 		RecordReplaceNode(node);
 		RecordReplaceNode(node);
 }
 }
 
 
 void BfResolvePassData::HandleMethodGenericParam(BfAstNode* node, BfTypeDef* typeDef, BfMethodDef* methodDef, int genericParamIdx)
 void BfResolvePassData::HandleMethodGenericParam(BfAstNode* node, BfTypeDef* typeDef, BfMethodDef* methodDef, int genericParamIdx)
 {
 {
-	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_MethodGenericParam) && (mSymbolReferenceTypeDef == typeDef) && (mSymbolReferenceMethodIdx == methodDef->mIdx) && (genericParamIdx == mSymbolMethodGenericParamIdx))
+	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_MethodGenericParam) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && 
+		(mSymbolReferenceMethodIdx == methodDef->mIdx) && (genericParamIdx == mSymbolMethodGenericParamIdx) && (!methodDef->mDeclaringType->IsEmitted()))
 		RecordReplaceNode(node);
 		RecordReplaceNode(node);
 }
 }
 
 
 void BfResolvePassData::HandleLocalReference(BfIdentifierNode* identifier, BfIdentifierNode* origNameNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx)
 void BfResolvePassData::HandleLocalReference(BfIdentifierNode* identifier, BfIdentifierNode* origNameNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx)
 {
 {
-	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Local) && (mSymbolReferenceTypeDef == typeDef) && (mSymbolReferenceMethodIdx == methodDef->mIdx) && (localVarIdx == mSymbolReferenceLocalIdx))
+	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Local) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && 
+		(mSymbolReferenceMethodIdx == methodDef->mIdx) && (localVarIdx == mSymbolReferenceLocalIdx) && (!methodDef->mDeclaringType->IsEmitted()))
 	{
 	{
 		if (origNameNode == NULL)
 		if (origNameNode == NULL)
 			origNameNode = identifier;
 			origNameNode = identifier;

+ 30 - 11
IDEHelper/Compiler/BfResolvedTypeUtils.cpp

@@ -1,4 +1,4 @@
-#include "BeefySysLib/util/AllocDebug.h"
+delete mConstHolder; #include "BeefySysLib/util/AllocDebug.h"
 
 
 #include "BfCompiler.h"
 #include "BfCompiler.h"
 #include "BfParser.h"
 #include "BfParser.h"
@@ -1551,6 +1551,11 @@ BfTypeInstance::~BfTypeInstance()
 		delete localMethod;
 		delete localMethod;
 	delete mHotTypeData;
 	delete mHotTypeData;
 	delete mConstHolder;
 	delete mConstHolder;
+	if ((mTypeDef != NULL) && (mTypeDef->mEmitParent != NULL))
+	{
+		mMethodInstanceGroups.Clear();
+		delete mTypeDef;
+	}
 }
 }
 
 
 void BfTypeInstance::ReleaseData()
 void BfTypeInstance::ReleaseData()
@@ -1564,6 +1569,13 @@ void BfTypeInstance::ReleaseData()
 	mInternalAccessMap.Clear();
 	mInternalAccessMap.Clear();
 }
 }
 
 
+void BfTypeInstance::Dispose()
+{
+	delete mGenericTypeInfo;
+	mGenericTypeInfo = NULL;
+	mTypeDef = NULL;
+}
+
 int BfTypeInstance::GetSplatCount()
 int BfTypeInstance::GetSplatCount()
 {
 {
 	if (IsValuelessType())
 	if (IsValuelessType())
@@ -1577,7 +1589,7 @@ int BfTypeInstance::GetSplatCount()
 
 
 bool BfTypeInstance::IsString()
 bool BfTypeInstance::IsString()
 { 
 { 
-	return mTypeDef == mContext->mCompiler->mStringTypeDef;
+	return IsInstanceOf(mContext->mCompiler->mStringTypeDef);
 }
 }
 
 
 int BfTypeInstance::GetOrigVTableSize()
 int BfTypeInstance::GetOrigVTableSize()
@@ -2277,7 +2289,7 @@ bool BfTypeInstance::IsSpecializedByAutoCompleteMethod()
 
 
 bool BfTypeInstance::IsNullable()
 bool BfTypeInstance::IsNullable()
 { 
 { 
-	return (mTypeDef == mContext->mCompiler->mNullableTypeDef);
+	return IsInstanceOf(mContext->mCompiler->mNullableTypeDef);
 }
 }
 
 
 bool BfTypeInstance::HasVarConstraints()
 bool BfTypeInstance::HasVarConstraints()
@@ -2463,7 +2475,10 @@ BfClosureType::~BfClosureType()
 {
 {
 	mMethodInstanceGroups.Clear();
 	mMethodInstanceGroups.Clear();
 	if (mCreatedTypeDef)
 	if (mCreatedTypeDef)
+	{
 		delete mTypeDef;
 		delete mTypeDef;
+		mTypeDef = NULL;
+	}
 	for (auto directAllocNode : mDirectAllocNodes)
 	for (auto directAllocNode : mDirectAllocNodes)
 		delete directAllocNode;
 		delete directAllocNode;
 }
 }
@@ -2542,6 +2557,7 @@ BfDelegateType::~BfDelegateType()
 {	
 {	
 	mMethodInstanceGroups.Clear();
 	mMethodInstanceGroups.Clear();
 	delete mTypeDef;	
 	delete mTypeDef;	
+	mTypeDef = NULL;
 }
 }
 
 
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
@@ -2559,7 +2575,10 @@ BfTupleType::~BfTupleType()
 {
 {
 	mMethodInstanceGroups.Clear();
 	mMethodInstanceGroups.Clear();
 	if (mCreatedTypeDef)
 	if (mCreatedTypeDef)
+	{
 		delete mTypeDef;
 		delete mTypeDef;
+		mTypeDef = NULL;
+	}
 	delete mSource;
 	delete mSource;
 }
 }
 
 
@@ -2694,7 +2713,7 @@ bool BfTypeVectorEquals::operator()(const BfTypeVector& lhs, const BfTypeVector&
 bool BfCustomAttributes::Contains(BfTypeDef* typeDef)
 bool BfCustomAttributes::Contains(BfTypeDef* typeDef)
 {
 {
 	for (auto& customAttr : mAttributes)
 	for (auto& customAttr : mAttributes)
-		if (customAttr.mType->mTypeDef == typeDef)
+		if (customAttr.mType->mTypeDef->GetDefinition() == typeDef)
 			return true;
 			return true;
 	return false;
 	return false;
 }
 }
@@ -2702,7 +2721,7 @@ bool BfCustomAttributes::Contains(BfTypeDef* typeDef)
 BfCustomAttribute* BfCustomAttributes::Get(BfTypeDef * typeDef)
 BfCustomAttribute* BfCustomAttributes::Get(BfTypeDef * typeDef)
 {
 {
 	for (auto& customAttr : mAttributes)
 	for (auto& customAttr : mAttributes)
-		if (customAttr.mType->mTypeDef == typeDef)
+		if (customAttr.mType->mTypeDef->GetDefinition() == typeDef)
 			return &customAttr;
 			return &customAttr;
 	return NULL;
 	return NULL;
 }
 }
@@ -3696,7 +3715,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
 			BfTypeInstance* rhsGenericType = (BfTypeInstance*)rhs;
 			BfTypeInstance* rhsGenericType = (BfTypeInstance*)rhs;
 			if (lhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size() != rhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size())
 			if (lhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size() != rhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size())
 				return false;
 				return false;
-			if (lhsGenericType->mTypeDef != rhsGenericType->mTypeDef)
+			if (lhsGenericType->mTypeDef->GetDefinition() != rhsGenericType->mTypeDef->GetDefinition())
 				return false;
 				return false;
 			for (int i = 0; i < (int)lhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); i++)
 			for (int i = 0; i < (int)lhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); i++)
 			{
 			{
@@ -3705,7 +3724,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
 			}
 			}
 		}
 		}
 
 
-		return lhsInst->mTypeDef == rhsInst->mTypeDef;
+		return lhsInst->mTypeDef->GetDefinition() == rhsInst->mTypeDef->GetDefinition();
 	}
 	}
 	else if (lhs->IsPrimitiveType())
 	else if (lhs->IsPrimitiveType())
 	{
 	{
@@ -3850,7 +3869,7 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType
 		if ((rhsTypeDef != NULL) && (rootOuterTypeInstance != NULL))
 		if ((rhsTypeDef != NULL) && (rootOuterTypeInstance != NULL))
 		{
 		{
 			// See if we're referring to an non-generic inner type where the outer type is generic
 			// See if we're referring to an non-generic inner type where the outer type is generic
-			if (lhsGenericType->mTypeDef != rhsTypeDef)
+			if (lhsGenericType->mTypeDef->GetDefinition() != rhsTypeDef->GetDefinition())
 				return false;
 				return false;
 
 
 			BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(rootOuterTypeInstance->mTypeDef, rhsTypeDef->mOuterType);
 			BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(rootOuterTypeInstance->mTypeDef, rhsTypeDef->mOuterType);
@@ -3881,7 +3900,7 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType
 	}
 	}
 
 
 	BfTypeDef* elementTypeDef = ctx->mModule->ResolveGenericInstanceDef(rhsGenericTypeInstRef);
 	BfTypeDef* elementTypeDef = ctx->mModule->ResolveGenericInstanceDef(rhsGenericTypeInstRef);
-	if (elementTypeDef != lhsGenericType->mTypeDef)
+	if (elementTypeDef->GetDefinition() != lhsGenericType->mTypeDef->GetDefinition())
 		return false;
 		return false;
 
 
 	int genericParamOffset = 0;
 	int genericParamOffset = 0;
@@ -3955,7 +3974,7 @@ BfTypeDef* BfResolvedTypeSet::LookupContext::ResolveToTypeDef(BfTypeReference* t
 	auto typeInst = type->ToTypeInstance();
 	auto typeInst = type->ToTypeInstance();
 	if (typeInst == NULL)
 	if (typeInst == NULL)
 		return NULL;
 		return NULL;
-	return typeInst->mTypeDef;
+	return typeInst->mTypeDef->GetDefinition();
 }
 }
 
 
 bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx)
 bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx)
@@ -4190,7 +4209,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
 			if (rhsTypeDef == NULL)
 			if (rhsTypeDef == NULL)
 				return false;
 				return false;
 
 
-			return lhsInst->mTypeDef == rhsTypeDef;
+			return lhsInst->IsInstanceOf(rhsTypeDef);
 		}		
 		}		
 	}
 	}
 	else if (lhs->IsPrimitiveType())
 	else if (lhs->IsPrimitiveType())

+ 5 - 4
IDEHelper/Compiler/BfResolvedTypeUtils.h

@@ -1822,7 +1822,7 @@ public:
 
 
 class BfCeTypeInfo
 class BfCeTypeInfo
 {
 {
-public:
+public:	
 	Dictionary<int, BfCeTypeEmitEntry> mOnCompileMap;
 	Dictionary<int, BfCeTypeEmitEntry> mOnCompileMap;
 	Dictionary<int, BfCeTypeEmitEntry> mTypeIFaceMap;
 	Dictionary<int, BfCeTypeEmitEntry> mTypeIFaceMap;
 	Val128 mHash;
 	Val128 mHash;
@@ -1833,7 +1833,7 @@ public:
 	BfCeTypeInfo()
 	BfCeTypeInfo()
 	{
 	{
 		mFailed = false;
 		mFailed = false;
-		mNext = NULL;
+		mNext = NULL;		
 	}
 	}
 };
 };
 
 
@@ -1963,9 +1963,10 @@ public:
 	
 	
 	~BfTypeInstance();	
 	~BfTypeInstance();	
 	
 	
-	void ReleaseData();
+	void Dispose();
+	void ReleaseData();	
 
 
-	virtual bool IsInstanceOf(BfTypeDef* typeDef) override { return typeDef == mTypeDef; }
+	virtual bool IsInstanceOf(BfTypeDef* typeDef) override { return typeDef->GetDefinition() == mTypeDef->GetDefinition(); }
 	virtual BfModule* GetModule() override { return mModule; }
 	virtual BfModule* GetModule() override { return mModule; }
 	virtual BfTypeInstance* ToTypeInstance() override { return this; }
 	virtual BfTypeInstance* ToTypeInstance() override { return this; }
 	virtual bool IsDependentOnUnderlyingType() override { return true; }
 	virtual bool IsDependentOnUnderlyingType() override { return true; }

+ 5 - 5
IDEHelper/Compiler/BfStmtEvaluator.cpp

@@ -3908,8 +3908,8 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
 		bool canAlwaysDelete = checkType->IsDelegate() || checkType->IsFunction() || checkType->IsArray();
 		bool canAlwaysDelete = checkType->IsDelegate() || checkType->IsFunction() || checkType->IsArray();
 		if (auto checkTypeInst = checkType->ToTypeInstance())
 		if (auto checkTypeInst = checkType->ToTypeInstance())
 		{
 		{
-			if ((checkTypeInst->mTypeDef == mCompiler->mDelegateTypeDef) || 
-				(checkTypeInst->mTypeDef == mCompiler->mFunctionTypeDef))
+			if ((checkTypeInst->IsInstanceOf(mCompiler->mDelegateTypeDef)) || 
+				(checkTypeInst->IsInstanceOf(mCompiler->mFunctionTypeDef)))
 				canAlwaysDelete = true;
 				canAlwaysDelete = true;
 		}
 		}
 
 
@@ -6064,7 +6064,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
 			if (genericParamInst->mTypeConstraint->IsGenericTypeInstance())
 			if (genericParamInst->mTypeConstraint->IsGenericTypeInstance())
 			{
 			{
 				auto genericConstraintType = (BfTypeInstance*)genericParamInst->mTypeConstraint;				
 				auto genericConstraintType = (BfTypeInstance*)genericParamInst->mTypeConstraint;				
-				if (genericConstraintType->mTypeDef == mCompiler->mSizedArrayTypeDef)
+				if (genericConstraintType->IsInstanceOf(mCompiler->mSizedArrayTypeDef))
 				{
 				{
 					varType = genericConstraintType->mGenericTypeInfo->mTypeGenericArguments[0];
 					varType = genericConstraintType->mGenericTypeInfo->mTypeGenericArguments[0];
 					isVarEnumerator = true;
 					isVarEnumerator = true;
@@ -6160,7 +6160,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
 
 
 			auto _CheckInterface = [&](BfTypeInstance* interface)
 			auto _CheckInterface = [&](BfTypeInstance* interface)
 			{
 			{
-				if (interface->mTypeDef == (isRefExpression ? mCompiler->mGenericIRefEnumeratorTypeDef : mCompiler->mGenericIEnumeratorTypeDef))
+				if (interface->IsInstanceOf(isRefExpression ? mCompiler->mGenericIRefEnumeratorTypeDef : mCompiler->mGenericIEnumeratorTypeDef))
 				{
 				{
 					if (genericItrInterface != NULL)
 					if (genericItrInterface != NULL)
 					{
 					{
@@ -6192,7 +6192,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
 					_CheckInterface(interface);	
 					_CheckInterface(interface);	
 				}
 				}
 
 
-				if (enumeratorTypeInst->mTypeDef == (isRefExpression ? mCompiler->mGenericIRefEnumeratorTypeDef : mCompiler->mGenericIEnumeratorTypeDef))
+				if (enumeratorTypeInst->IsInstanceOf(isRefExpression ? mCompiler->mGenericIRefEnumeratorTypeDef : mCompiler->mGenericIEnumeratorTypeDef))
 				{
 				{
 					itrInterface = enumeratorTypeInst;
 					itrInterface = enumeratorTypeInst;
 					genericItrInterface = itrInterface->ToGenericTypeInstance();
 					genericItrInterface = itrInterface->ToGenericTypeInstance();

+ 297 - 57
IDEHelper/Compiler/BfSystem.cpp

@@ -611,7 +611,7 @@ void BfTypeDef::Reset()
 
 
 void BfTypeDef::FreeMembers()
 void BfTypeDef::FreeMembers()
 {	
 {	
-	if (!mIsCombinedPartial)
+	if ((!mIsCombinedPartial) && (mEmitParent == NULL))
 		mSystem->RemoveNamespaceUsage(mNamespace, mProject);	
 		mSystem->RemoveNamespaceUsage(mNamespace, mProject);	
 
 
 	if (mName != NULL)
 	if (mName != NULL)
@@ -679,53 +679,6 @@ void BfTypeDef::FreeMembers()
 	mIsNextRevision = false;
 	mIsNextRevision = false;
 }
 }
 
 
-void BfTypeDef::ClearEmitted()
-{
-	for (auto& partial : mPartials)
-		partial->ClearEmitted();
-
-	if (mEmitParser != NULL)
-	{
-		mEmitParser->mRefCount--;
-		BF_ASSERT(mEmitParser->mRefCount >= 0);
-		mEmitParser = NULL;
-	}
-
-	if (mHasEmitMembers)
-	{
-		for (int methodIdx = (int)mMethods.size() - 1; methodIdx >= 0; methodIdx--)
-		{
-			auto methodDef = mMethods[methodIdx];
-			if ((methodDef->mAddedAfterEmit) ||
-				((methodDef->mMethodDeclaration != NULL) && (methodDef->mMethodDeclaration->IsEmitted())))
-			{
-				delete methodDef;
-				mMethods.RemoveAt(methodIdx);
-			}
-		}
-
-		for (int fieldIdx = (int)mFields.size() - 1; fieldIdx >= 0; fieldIdx--)
-		{
-			auto fieldDef = mFields[fieldIdx];
-			if ((fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->IsEmitted()))
-			{
-				delete fieldDef;
-				mFields.RemoveAt(fieldIdx);
-			}
-		}
-
-		for (int propIdx = (int)mProperties.size() - 1; propIdx >= 0; propIdx--)
-		{
-			auto propDef = mProperties[propIdx];
-			if ((propDef->mFieldDeclaration != NULL) && (propDef->mFieldDeclaration->IsEmitted()))
-			{
-				delete propDef;
-				mProperties.RemoveAt(propIdx);
-			}
-		}
-	}
-}
-
 void BfTypeDef::PopulateMemberSets()
 void BfTypeDef::PopulateMemberSets()
 {
 {
 	if ((!mMethodSet.IsEmpty()) || (!mFieldSet.IsEmpty()) || (!mPropertySet.IsEmpty()))
 	if ((!mMethodSet.IsEmpty()) || (!mFieldSet.IsEmpty()) || (!mPropertySet.IsEmpty()))
@@ -783,9 +736,39 @@ void BfTypeDef::ClearMemberSets()
 	mPropertySet.Clear();
 	mPropertySet.Clear();
 }
 }
 
 
+void BfTypeDef::ClearOldMemberSets()
+{
+	if ((mMethodSet.mCount > 0) && (mMethods.mSize > mMethodSet.mCount))
+	{
+		for (auto entry : mMethodSet)
+			((BfMethodDef*)entry.mMemberDef)->mNextWithSameName = NULL;
+		mMethodSet.Clear();
+	}
+
+	if ((mFieldSet.mCount > 0) && (mFields.mSize > mFieldSet.mCount))
+	{
+		for (auto entry : mFieldSet)
+			((BfFieldDef*)entry.mMemberDef)->mNextWithSameName = NULL;
+		mFieldSet.Clear();
+	}
+
+	if ((mPropertySet.mCount > 0) && (mProperties.mSize > mPropertySet.mCount))
+	{
+		for (auto entry : mPropertySet)
+			((BfPropertyDef*)entry.mMemberDef)->mNextWithSameName = NULL;
+		mPropertySet.Clear();
+	}
+}
+
 BfTypeDef::~BfTypeDef()
 BfTypeDef::~BfTypeDef()
 {
 {
-	BfLogSysM("BfTypeDef::~BfTypeDef %08X\n", this);
+	BfLogSysM("BfTypeDef::~BfTypeDef %p\n", this);
+
+	if ((mHash == -1330357811) && (IsEmitted()))
+	{
+		NOP;
+	}
+
 	delete mNextRevision;
 	delete mNextRevision;
 	FreeMembers();
 	FreeMembers();
 
 
@@ -794,12 +777,6 @@ BfTypeDef::~BfTypeDef()
 		mSource->mRefCount--;
 		mSource->mRefCount--;
 		BF_ASSERT(mSource->mRefCount >= 0);
 		BF_ASSERT(mSource->mRefCount >= 0);
 	}
 	}
-
-	if (mEmitParser != NULL)
-	{
-		mEmitParser->mRefCount--;
-		BF_ASSERT(mEmitParser->mRefCount >= 0);
-	}
 }
 }
 
 
 BfSource* BfTypeDef::GetLastSource()
 BfSource* BfTypeDef::GetLastSource()
@@ -2679,7 +2656,10 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
 {
 {
 	BfLogSys(this, "InjectNewRevision from %p (decl:%p) into %p (decl:%p)\n", typeDef->mNextRevision, typeDef->mNextRevision->mTypeDeclaration, typeDef, typeDef->mTypeDeclaration);
 	BfLogSys(this, "InjectNewRevision from %p (decl:%p) into %p (decl:%p)\n", typeDef->mNextRevision, typeDef->mNextRevision->mTypeDeclaration, typeDef, typeDef->mTypeDeclaration);
 
 
-	typeDef->ClearEmitted();
+	if (typeDef->mName->ToString() == "Zonk")
+	{
+		NOP;
+	}
 
 
 	bool setDeclaringType = !typeDef->mIsCombinedPartial;
 	bool setDeclaringType = !typeDef->mIsCombinedPartial;
 
 
@@ -2740,7 +2720,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
 				methodDef->mCodeChanged = true;
 				methodDef->mCodeChanged = true;
 			nextMethodDef->mParams.Clear();
 			nextMethodDef->mParams.Clear();
 			nextMethodDef->mGenericParams.Clear();
 			nextMethodDef->mGenericParams.Clear();
-		}						
+		}
 	}
 	}
 	else
 	else
 	{	
 	{	
@@ -3197,6 +3177,266 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef)
 	VerifyTypeDef(nextRevision);
 	VerifyTypeDef(nextRevision);
 }
 }
 
 
+void BfSystem::CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* fromTypeDef)
+{
+	BfLogSys(this, "CopyTypeDef %p from %p Hash: %d\n", typeDef, fromTypeDef, fromTypeDef->mHash);
+
+	for (auto fromMethodDef : fromTypeDef->mMethods)
+	{		
+		BfMethodDef* methodDef;
+		if (fromMethodDef->mIsOperator)
+		{
+			auto fromOperatorDef = (BfOperatorDef*)fromMethodDef;
+			auto operatorDef = new BfOperatorDef();
+			methodDef = operatorDef;
+			*operatorDef = *fromOperatorDef;
+		}
+		else
+		{
+			methodDef = new BfMethodDef();
+			*methodDef = *fromMethodDef;
+		}					
+
+		for (int paramIdx = 0; paramIdx < fromMethodDef->mParams.mSize; paramIdx++)
+		{
+			auto fromParamDef = fromMethodDef->mParams[paramIdx];
+			BfParameterDef* paramDef = new BfParameterDef();
+			*paramDef = *fromParamDef;			
+			methodDef->mParams[paramIdx] = paramDef;
+		}
+
+		for (int genericParamIdx = 0; genericParamIdx < fromMethodDef->mGenericParams.mSize; genericParamIdx++)
+		{
+			auto fromGenericParam = fromMethodDef->mGenericParams[genericParamIdx];
+			BfGenericParamDef* genericParam = new BfGenericParamDef();
+			*genericParam = *fromGenericParam;
+			methodDef->mGenericParams[genericParamIdx] = genericParam;
+		}
+
+		methodDef->mNextWithSameName = NULL;
+		typeDef->mMethods.Add(methodDef);
+	}
+
+	for (auto operatorDef : fromTypeDef->mOperators)
+	{
+		auto methodDef = typeDef->mMethods[operatorDef->mIdx];
+		BF_ASSERT(methodDef->mIsOperator);
+		if (methodDef->mIsOperator)
+			typeDef->mOperators.Add((BfOperatorDef*)methodDef);
+	}
+
+	for (auto fromPropDef : fromTypeDef->mProperties)
+	{		
+		BfPropertyDef* propDef = new BfPropertyDef();		
+		*propDef = *fromPropDef;
+		for (auto& methodDef : propDef->mMethods)		
+			methodDef = typeDef->mMethods[methodDef->mIdx];		
+		propDef->mNextWithSameName = NULL;
+		typeDef->mProperties.Add(propDef);
+	}
+
+	for (auto fromField : fromTypeDef->mFields)
+	{
+		BfFieldDef* fieldDef = new BfFieldDef();
+		*fieldDef = *fromField;
+		fieldDef->mNextWithSameName = NULL;
+		typeDef->mFields.Add(fieldDef);
+	}
+		
+	typeDef->mSystem = fromTypeDef->mSystem;
+	typeDef->mProject = fromTypeDef->mProject;
+	typeDef->mPartialIdx = fromTypeDef->mPartialIdx;
+	typeDef->mTypeDeclaration = fromTypeDef->mTypeDeclaration;
+	typeDef->mHash = fromTypeDef->mHash;
+	typeDef->mSignatureHash = fromTypeDef->mSignatureHash;
+	typeDef->mFullHash = fromTypeDef->mFullHash;
+	typeDef->mInlineHash = fromTypeDef->mInlineHash;
+	typeDef->mNestDepth = fromTypeDef->mNestDepth;
+
+	typeDef->mOuterType = fromTypeDef->mOuterType;
+	//typeDef->mOuterType = fromTypeDef->mOuterType;	
+	typeDef->mNamespace = fromTypeDef->mNamespace;	
+
+	typeDef->mName = fromTypeDef->mName;
+	if (typeDef->mName != mEmptyAtom)
+		typeDef->mName->mRefCount++;
+
+	//typeDef->mName = fromTypeDef->mName;
+	typeDef->mNameEx = fromTypeDef->mNameEx;
+	if (typeDef->mNameEx != NULL)
+		typeDef->mNameEx->mRefCount++;	
+	//typeDef->mNameEx = fromTypeDef->mNameEx;
+	//typeDef->mFullName = fromTypeDef->mFullName;
+
+	typeDef->mFullNameEx = fromTypeDef->mFullNameEx;
+	//RefAtomComposite(typeDef->mFullNameEx);
+
+	typeDef->mProtection = fromTypeDef->mProtection;
+
+	typeDef->mTypeCode = fromTypeDef->mTypeCode;
+
+	typeDef->mTypeCode = fromTypeDef->mTypeCode;
+
+	typeDef->mIsAlwaysInclude = fromTypeDef->mIsAlwaysInclude;
+	typeDef->mIsNoDiscard = fromTypeDef->mIsNoDiscard;
+	typeDef->mIsPartial = fromTypeDef->mIsPartial;
+	typeDef->mIsExplicitPartial = fromTypeDef->mIsExplicitPartial;
+	//mPartialUsed	
+	typeDef->mIsCombinedPartial = fromTypeDef->mIsCombinedPartial;
+	typeDef->mIsDelegate = fromTypeDef->mIsDelegate;
+	typeDef->mIsFunction = fromTypeDef->mIsFunction;
+	typeDef->mIsClosure = fromTypeDef->mIsClosure;
+	typeDef->mIsAbstract = fromTypeDef->mIsAbstract;
+	typeDef->mIsStatic = fromTypeDef->mIsStatic;
+	typeDef->mHasAppendCtor = fromTypeDef->mHasAppendCtor;
+	typeDef->mHasCEOnCompile = fromTypeDef->mHasCEOnCompile;
+	typeDef->mHasCtorNoBody = fromTypeDef->mHasCtorNoBody;
+	typeDef->mHasOverrideMethods = fromTypeDef->mHasOverrideMethods;
+	typeDef->mHasExtensionMethods = fromTypeDef->mHasExtensionMethods;
+	typeDef->mIsOpaque = fromTypeDef->mIsOpaque;
+
+	typeDef->mDupDetectedRevision = fromTypeDef->mDupDetectedRevision;
+	
+	typeDef->mDirectAllocNodes = fromTypeDef->mDirectAllocNodes;
+	fromTypeDef->mDirectAllocNodes.Clear();
+	
+	typeDef->mNamespaceSearch = fromTypeDef->mNamespaceSearch;
+	for (auto name : typeDef->mNamespaceSearch)
+		RefAtomComposite(name);
+
+	typeDef->mStaticSearch = fromTypeDef->mStaticSearch;
+	typeDef->mInternalAccessSet = fromTypeDef->mInternalAccessSet;
+	
+	for (auto fromGenericParamDef : fromTypeDef->mGenericParamDefs)
+	{
+		BfGenericParamDef* genericParamDef = new BfGenericParamDef();
+		*genericParamDef = *fromGenericParamDef;
+		typeDef->mGenericParamDefs.Add(genericParamDef);
+	}	
+
+	typeDef->mExternalConstraints = fromTypeDef->mExternalConstraints;	
+
+	typeDef->mBaseTypes = fromTypeDef->mBaseTypes;
+	typeDef->mNestedTypes = fromTypeDef->mNestedTypes;
+	
+	typeDef->mPartials = fromTypeDef->mPartials;
+			
+	VerifyTypeDef(typeDef);
+}
+
+void BfSystem::UpdateEmittedTypeDef(BfTypeDef* typeDef)
+{
+	auto fromTypeDef = typeDef->mEmitParent;
+
+	BF_ASSERT(fromTypeDef->mNextRevision == NULL);
+
+	BfLogSys(this, "UpdateTypeDefCopy %p from %p (decl:%p)\n", typeDef, fromTypeDef, fromTypeDef->mTypeDeclaration);
+
+	BF_ASSERT((typeDef->mDefState == BfTypeDef::DefState_Emitted) || (typeDef->mDefState == BfTypeDef::DefState_EmittedDirty));
+	BF_ASSERT((fromTypeDef->mDefState != BfTypeDef::DefState_Emitted) && (fromTypeDef->mDefState != BfTypeDef::DefState_EmittedDirty));
+
+	typeDef->mTypeDeclaration = fromTypeDef->mTypeDeclaration;
+	typeDef->mOuterType = fromTypeDef->mOuterType;
+
+	for (int methodIdx = 0; methodIdx < (int)typeDef->mMethods.size(); methodIdx++)
+	{		
+		auto methodDef = typeDef->mMethods[methodIdx];
+		if (methodIdx >= fromTypeDef->mMethods.mSize)
+		{
+			BF_ASSERT(methodDef->mDeclaringType == typeDef);
+			continue;
+		}
+
+		BF_ASSERT(methodDef->mDeclaringType != typeDef);
+
+		for (auto param : methodDef->mParams)
+			delete param;
+		for (auto genericParam : methodDef->mGenericParams)
+			delete genericParam;
+
+		auto fromMethodDef = fromTypeDef->mMethods[methodIdx];
+
+		if ((fromMethodDef->mIsOperator) && (methodDef->mIsOperator))
+		{
+			auto fromOperatorDef = (BfOperatorDef*)fromMethodDef;
+			auto operatorDef = (BfOperatorDef*)methodDef;
+			*operatorDef = *fromOperatorDef;
+		}
+		else
+		{
+			*methodDef = *fromMethodDef;
+		}
+
+		for (int paramIdx = 0; paramIdx < fromMethodDef->mParams.mSize; paramIdx++)
+		{
+			auto fromParamDef = fromMethodDef->mParams[paramIdx];
+			BfParameterDef* paramDef = new BfParameterDef();
+			*paramDef = *fromParamDef;
+			methodDef->mParams[paramIdx] = paramDef;
+		}
+
+		for (int genericParamIdx = 0; genericParamIdx < fromMethodDef->mGenericParams.mSize; genericParamIdx++)
+		{
+			auto fromGenericParam = fromMethodDef->mGenericParams[genericParamIdx];
+			BfGenericParamDef* genericParam = new BfGenericParamDef();
+			*genericParam = *fromGenericParam;
+			methodDef->mGenericParams[genericParamIdx] = genericParam;
+		}						
+	}
+
+	typeDef->mOperators.Clear();
+	for (auto operatorDef : fromTypeDef->mOperators)
+	{
+		auto methodDef = typeDef->mMethods[operatorDef->mIdx];
+		BF_ASSERT(methodDef->mIsOperator);
+		if (methodDef->mIsOperator)
+			typeDef->mOperators.Add((BfOperatorDef*)methodDef);
+	}
+
+	for (int fieldIdx = 0; fieldIdx < typeDef->mFields.mSize; fieldIdx++)
+	{
+		auto fieldDef = typeDef->mMethods[fieldIdx];
+		if (fieldIdx >= fromTypeDef->mFields.mSize)
+		{
+			BF_ASSERT(fieldDef->mDeclaringType == typeDef);
+			continue;
+		}
+
+		BF_ASSERT(fieldDef->mDeclaringType != typeDef);
+		auto fromFieldDef = fromTypeDef->mMethods[fieldIdx];
+		fieldDef->mDeclaringType = fromFieldDef->mDeclaringType;
+	}
+
+	for (int propertyIdx = 0; propertyIdx < typeDef->mProperties.mSize; propertyIdx++)
+	{
+		auto propertyDef = typeDef->mProperties[propertyIdx];
+		if (propertyIdx >= fromTypeDef->mProperties.mSize)
+		{
+			BF_ASSERT(propertyDef->mDeclaringType == typeDef);
+			continue;
+		}
+
+		BF_ASSERT(propertyDef->mDeclaringType != typeDef);
+		auto fromPropertyDef = fromTypeDef->mProperties[propertyIdx];
+		propertyDef->mDeclaringType = fromPropertyDef->mDeclaringType;
+	}	
+
+	typeDef->mGenericParamDefs.Clear();
+	for (auto fromGenericParamDef : fromTypeDef->mGenericParamDefs)
+	{
+		BfGenericParamDef* genericParamDef = new BfGenericParamDef();
+		*genericParamDef = *fromGenericParamDef;
+		typeDef->mGenericParamDefs.Add(genericParamDef);
+	}
+
+	typeDef->mPartials = fromTypeDef->mPartials;
+
+	if (typeDef->mDefState == BfTypeDef::DefState_EmittedDirty)
+		typeDef->mDefState = BfTypeDef::DefState_Emitted;
+
+	BF_ASSERT(typeDef->mDefState == BfTypeDef::DefState_Emitted);
+}
+
 BfTypeDef* BfSystem::GetCombinedPartial(BfTypeDef* typeDef)
 BfTypeDef* BfSystem::GetCombinedPartial(BfTypeDef* typeDef)
 {
 {
 	if ((!typeDef->mIsPartial) || (typeDef->mIsCombinedPartial))
 	if ((!typeDef->mIsPartial) || (typeDef->mIsCombinedPartial))

+ 24 - 10
IDEHelper/Compiler/BfSystem.h

@@ -941,7 +941,9 @@ public:
 		DefState_InlinedInternals_Changed, // Code within methods, including inlined methods, changed
 		DefState_InlinedInternals_Changed, // Code within methods, including inlined methods, changed
 		DefState_Internals_Changed, // Only code within a non-inlined methods changed
 		DefState_Internals_Changed, // Only code within a non-inlined methods changed
 		DefState_Refresh,
 		DefState_Refresh,
-		DefState_Deleted
+		DefState_Deleted,
+		DefState_Emitted,
+		DefState_EmittedDirty
 	};
 	};
 
 
 public:
 public:
@@ -950,13 +952,13 @@ public:
 	BfSystem* mSystem;
 	BfSystem* mSystem;
 	BfProject* mProject;
 	BfProject* mProject;
 	BfTypeDeclaration* mTypeDeclaration;
 	BfTypeDeclaration* mTypeDeclaration;
-	BfSource* mSource;
-	BfParser* mEmitParser;
+	BfSource* mSource;	
 	DefState mDefState;	
 	DefState mDefState;	
 	Val128 mSignatureHash; // Data, methods, etc
 	Val128 mSignatureHash; // Data, methods, etc
 	Val128 mFullHash;	
 	Val128 mFullHash;	
 	Val128 mInlineHash;
 	Val128 mInlineHash;
 	
 	
+	BfTypeDef* mEmitParent;
 	BfTypeDef* mOuterType;
 	BfTypeDef* mOuterType;
 	BfAtomComposite mNamespace;
 	BfAtomComposite mNamespace;
 	BfAtom* mName;
 	BfAtom* mName;
@@ -1004,8 +1006,7 @@ public:
 	bool mHasOverrideMethods;	
 	bool mHasOverrideMethods;	
 	bool mIsOpaque;
 	bool mIsOpaque;
 	bool mIsNextRevision;
 	bool mIsNextRevision;
-	bool mInDeleteQueue;
-	bool mHasEmitMembers;
+	bool mInDeleteQueue;	
 	bool mForceUseNextRevision;
 	bool mForceUseNextRevision;
 
 
 public:
 public:
@@ -1029,8 +1030,7 @@ public:
 		mIsPartial = false;
 		mIsPartial = false;
 		mIsCombinedPartial = false;
 		mIsCombinedPartial = false;
 		mTypeDeclaration = NULL;
 		mTypeDeclaration = NULL;
-		mSource = NULL;
-		mEmitParser = NULL;
+		mSource = NULL;		
 		mDefState = DefState_New;
 		mDefState = DefState_New;
 		mHash = 0;		
 		mHash = 0;		
 		mPartialIdx = -1;
 		mPartialIdx = -1;
@@ -1047,11 +1047,11 @@ public:
 		mIsOpaque = false;
 		mIsOpaque = false;
 		mPartialUsed = false;
 		mPartialUsed = false;
 		mIsNextRevision = false;
 		mIsNextRevision = false;
-		mInDeleteQueue = false;
-		mHasEmitMembers = false;
+		mInDeleteQueue = false;		
 		mForceUseNextRevision = false;
 		mForceUseNextRevision = false;
 		mDupDetectedRevision = -1;
 		mDupDetectedRevision = -1;
 		mNestDepth = 0;
 		mNestDepth = 0;
+		mEmitParent = NULL;
 		mOuterType = NULL;
 		mOuterType = NULL;
 		mTypeDeclaration = NULL;		
 		mTypeDeclaration = NULL;		
 		mNextRevision = NULL;		
 		mNextRevision = NULL;		
@@ -1062,9 +1062,9 @@ public:
 	bool IsGlobalsContainer();	
 	bool IsGlobalsContainer();	
 	void Reset();
 	void Reset();
 	void FreeMembers();
 	void FreeMembers();
-	void ClearEmitted();
 	void PopulateMemberSets();
 	void PopulateMemberSets();
 	void ClearMemberSets();
 	void ClearMemberSets();
+	void ClearOldMemberSets();
 	void RemoveGenericParamDef(BfGenericParamDef* genericParamDef);	
 	void RemoveGenericParamDef(BfGenericParamDef* genericParamDef);	
 	int GetSelfGenericParamCount();
 	int GetSelfGenericParamCount();
 	String ToString();
 	String ToString();
@@ -1074,8 +1074,19 @@ public:
 	String GetAutoPropertyName(BfPropertyDeclaration* propertyDeclaration);
 	String GetAutoPropertyName(BfPropertyDeclaration* propertyDeclaration);
 	BfAstNode* GetRefNode();
 	BfAstNode* GetRefNode();
 
 
+	bool IsEmitted() { return mEmitParent != NULL; }
+
+	BfTypeDef* GetDefinition()
+	{
+		if (mEmitParent != NULL)
+			return mEmitParent;
+		return this;
+	}
+
 	BfTypeDef* GetLatest()
 	BfTypeDef* GetLatest()
 	{
 	{
+		if (mEmitParent != NULL)
+			return mEmitParent->GetLatest();
 		if (mNextRevision != NULL)
 		if (mNextRevision != NULL)
 			return mNextRevision;
 			return mNextRevision;
 		return this;
 		return this;
@@ -1612,6 +1623,9 @@ public:
 	void InjectNewRevision(BfTypeDef* typeDef);
 	void InjectNewRevision(BfTypeDef* typeDef);
 	void AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* compositeTypeDef, BfTypeDef* partialTypeDef);
 	void AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* compositeTypeDef, BfTypeDef* partialTypeDef);
 	void FinishCompositePartial(BfTypeDef* compositeTypeDef);	
 	void FinishCompositePartial(BfTypeDef* compositeTypeDef);	
+	void CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* nextTypeDef);
+	void UpdateEmittedTypeDef(BfTypeDef* typeDef);
+
 	BfTypeDef* GetCombinedPartial(BfTypeDef* typeDef);
 	BfTypeDef* GetCombinedPartial(BfTypeDef* typeDef);
 	BfTypeDef* GetOuterTypeNonPartial(BfTypeDef* typeDef);
 	BfTypeDef* GetOuterTypeNonPartial(BfTypeDef* typeDef);