Brian Fiete пре 3 година
родитељ
комит
44ecb92315

+ 8 - 1
IDE/src/ui/RenameSymbolDialog.bf

@@ -493,7 +493,7 @@ namespace IDE.ui
 			for (var parserDataStr in mModifiedParsers.Split('\n'))
 			{
 			    if (parserDataStr == "")
-			        return;
+			        break;
 			    var parserData = parserDataStr.Split('\t');
 			    //var projectSource = IDEApp.sApp.FindProjectSourceItem(parserData[0]);
 				var filePath = parserData.GetNext().Get();
@@ -549,6 +549,13 @@ namespace IDE.ui
 			    mUpdatingProjectSources.Add(replaceSymbolData);
 			}
 
+			if ((mKind == .Rename) && (mUpdatingProjectSources.IsEmpty))
+			{
+				gApp.Fail("Cannot rename element");
+				Close();
+				return;
+			}
+
 			if (mKind == Kind.FindAllReferences)
 			{
 				PrintAllReferences();

+ 10 - 1
IDE/src/ui/SourceEditWidgetContent.bf

@@ -4474,7 +4474,16 @@ namespace IDE.ui
 
 				if (wantCursorPos != -1)
 				{
-					mSelection = null;
+					if (mWidgetWindow.IsKeyDown(.Shift))
+					{
+						if (mSelection == null)
+							mSelection = .(CursorTextPos, wantCursorPos);
+						else
+							mSelection.ValueRef.mEndPos = (.)wantCursorPos;
+					}
+					else
+						mSelection = null;
+
 					CursorTextPos = wantCursorPos;
 					return;
 				}

+ 18 - 14
IDEHelper/Compiler/BfAutoComplete.cpp

@@ -758,7 +758,8 @@ void BfAutoComplete::AddField(BfTypeInstance* typeInst, BfFieldDef* fieldDef, Bf
 	AutoCompleteEntry entry(GetTypeName(fieldInstance->mResolvedType), fieldDef->mName, fieldDef->mNamePrefixCount - wantPrefixCount);
 	if (auto entryAdded = AddEntry(entry, filterStr))
 	{
-		auto documentation = (fieldDef->mFieldDeclaration != NULL) ? fieldDef->mFieldDeclaration->mDocumentation : NULL;
+		auto fieldDecl = fieldDef->GetFieldDeclaration();
+		auto documentation = (fieldDecl != NULL) ? fieldDecl->mDocumentation : NULL;
 		if (CheckDocumentation(entryAdded, documentation))
 		{
 			mModule->PopulateType(typeInst);
@@ -786,8 +787,8 @@ void BfAutoComplete::AddField(BfTypeInstance* typeInst, BfFieldDef* fieldDef, Bf
 		{
 			mDefType = typeInst->mTypeDef;
 			mDefField = fieldDef;
-			if (fieldDef->mFieldDeclaration != NULL)
-				SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode);
+			if (auto nameNode = fieldDef->GetNameNode())
+				SetDefinitionLocation(nameNode);
 		}
 	}
 }
@@ -802,8 +803,9 @@ void BfAutoComplete::AddProp(BfTypeInstance* typeInst, BfPropertyDef* propDef, c
 		wantPrefixCount++;
 	}	
 	BfCommentNode* documentation = NULL;
-	if (propDef->mFieldDeclaration != NULL)
-		documentation = propDef->mFieldDeclaration->mDocumentation;
+	auto fieldDecl = propDef->GetFieldDeclaration();
+	if (fieldDecl != NULL)
+		documentation = fieldDecl->mDocumentation;
 	AutoCompleteEntry entry("property", propDef->mName, propDef->mNamePrefixCount - wantPrefixCount);
 	if (auto entryAdded = AddEntry(entry, filterStr))
 	{
@@ -861,8 +863,8 @@ void BfAutoComplete::AddProp(BfTypeInstance* typeInst, BfPropertyDef* propDef, c
 			}
 			entryAdded->mDocumentation = mAlloc.AllocString(str);
 		}
-		if ((mIsGetDefinition) && (propDef->mFieldDeclaration != NULL))
-			SetDefinitionLocation(propDef->mFieldDeclaration->mNameNode);
+		if ((mIsGetDefinition) && (fieldDecl != NULL))
+			SetDefinitionLocation(fieldDecl->mNameNode);
 	}
 }
 
@@ -1168,7 +1170,7 @@ void BfAutoComplete::AddEnumTypeMembers(BfTypeInstance* typeInst, const StringIm
 			AutoCompleteEntry entry(hasPayload ? "payloadEnum" : "value", fieldDef->mName);
 			if (auto entryAdded = AddEntry(entry, filter))
 			{
-				if (CheckDocumentation(entryAdded, fieldDef->mFieldDeclaration->mDocumentation))
+				if (CheckDocumentation(entryAdded, fieldDef->GetFieldDeclaration()->mDocumentation))
 				{
 				}
 
@@ -1177,7 +1179,7 @@ void BfAutoComplete::AddEnumTypeMembers(BfTypeInstance* typeInst, const StringIm
 					mDefType = typeInst->mTypeDef;
 					mDefField = fieldDef;
 					if (fieldDef->mFieldDeclaration != NULL)
-						SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode);
+						SetDefinitionLocation(fieldDef->GetFieldDeclaration()->mNameNode);
 				}
 			}
 		}
@@ -1296,7 +1298,9 @@ BfProject* BfAutoComplete::GetActiveProject()
 bool BfAutoComplete::WantsEntries()
 {
 	return (mResolveType == BfResolveType_Autocomplete) || 
-		(mResolveType == BfResolveType_Autocomplete_HighPri);
+		(mResolveType == BfResolveType_Autocomplete_HighPri) ||
+		(mResolveType == BfResolveType_GetSymbolInfo) ||
+		(mResolveType == BfResolveType_GoToDefinition);
 }
 
 void BfAutoComplete::AddTopLevelNamespaces(BfAstNode* identifierNode)
@@ -1521,12 +1525,12 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
 		{
 			if (auto entryAdded = AddEntry(AutoCompleteEntry("property", prop->mName + "="), filter))
 			{	
-				if (CheckDocumentation(entryAdded, prop->mFieldDeclaration->mDocumentation))
+				if (CheckDocumentation(entryAdded, prop->GetFieldDeclaration()->mDocumentation))
 				{
 
 				}
 				if (mIsGetDefinition)
-					SetDefinitionLocation(prop->mFieldDeclaration->mNameNode);
+					SetDefinitionLocation(prop->GetFieldDeclaration()->mNameNode);
 			}
 		}
 
@@ -1534,12 +1538,12 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
 		{			
 			if (auto entryAdded = AddEntry(AutoCompleteEntry("field", field->mName + "="), filter))
 			{	
-				if (CheckDocumentation(entryAdded, field->mFieldDeclaration->mDocumentation))
+				if (CheckDocumentation(entryAdded, field->GetFieldDeclaration()->mDocumentation))
 				{
 
 				}
 				if (mIsGetDefinition)
-					SetDefinitionLocation(field->mFieldDeclaration->mNameNode);
+					SetDefinitionLocation(field->GetFieldDeclaration()->mNameNode);
 			}
 		}
 	}

+ 33 - 30
IDEHelper/Compiler/BfCompiler.cpp

@@ -4508,15 +4508,14 @@ void BfCompiler::ProcessAutocompleteTempType()
 	for (auto fieldDef : tempTypeDef->mFields)
 	{
 		BP_ZONE("ProcessAutocompleteTempType.CheckField");		
-
-		auto fieldDecl = fieldDef->mFieldDeclaration;
-		if (BfNodeIsA<BfPropertyDeclaration>(fieldDecl))
+		
+		if (BfNodeIsA<BfPropertyDeclaration>(fieldDef->mFieldDeclaration))
 			continue; // Don't process auto-generated property fields
 
 		if (fieldDef->mTypeRef != NULL)
 		{
 			BfResolveTypeRefFlags flags = BfResolveTypeRefFlag_None;
-			if ((fieldDecl != NULL) && (fieldDecl->mInitializer != NULL))
+			if (fieldDef->GetInitializer() != NULL)
 				flags = (BfResolveTypeRefFlags)(flags | BfResolveTypeRefFlag_AllowInferredSizedArray);
 			if ((!BfNodeIsA<BfVarTypeReference>(fieldDef->mTypeRef)) &&
 				(!BfNodeIsA<BfLetTypeReference>(fieldDef->mTypeRef)))
@@ -4544,8 +4543,9 @@ void BfCompiler::ProcessAutocompleteTempType()
 			autoComplete->CheckVarResolution(fieldDef->mTypeRef, fieldInstance->mResolvedType);
 		}
 
+		auto nameNode = fieldDef->GetNameNode();
 		if (((autoComplete->mIsGetDefinition)  || (autoComplete->mResolveType == BfResolveType_GetResultString)) &&
-			(fieldDef->mFieldDeclaration != NULL) && (autoComplete->IsAutocompleteNode(fieldDef->mFieldDeclaration->mNameNode)))
+			(fieldDef->mFieldDeclaration != NULL) && (autoComplete->IsAutocompleteNode(nameNode)))
 		{
 			for (int i = 0; i < (int)actualTypeDef->mFields.size(); i++)
 			{
@@ -4557,9 +4557,9 @@ void BfCompiler::ProcessAutocompleteTempType()
 						autoComplete->mDefType = actualTypeDef;
 						autoComplete->mDefField = actualFieldDef;
 
-						autoComplete->SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode);
-						autoComplete->mInsertStartIdx = fieldDef->mFieldDeclaration->mNameNode->GetSrcStart();
-						autoComplete->mInsertEndIdx = fieldDef->mFieldDeclaration->mNameNode->GetSrcEnd();
+						autoComplete->SetDefinitionLocation(nameNode);
+						autoComplete->mInsertStartIdx = nameNode->GetSrcStart();
+						autoComplete->mInsertEndIdx = nameNode->GetSrcEnd();
 					}
 					else if (autoComplete->mResolveType == BfResolveType_GetResultString)
 					{
@@ -4577,9 +4577,10 @@ void BfCompiler::ProcessAutocompleteTempType()
 			}			
 		}
 
-		if ((fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mAttributes != NULL))
+		BfFieldDeclaration* fieldDecl = fieldDef->GetFieldDeclaration();
+		if ((fieldDecl != NULL) && (fieldDecl->mAttributes != NULL))
 		{
-			auto customAttrs = module->GetCustomAttributes(fieldDef->mFieldDeclaration->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
+			auto customAttrs = module->GetCustomAttributes(fieldDecl->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
 			delete customAttrs;
 		}
 
@@ -4588,15 +4589,12 @@ void BfCompiler::ProcessAutocompleteTempType()
 			module->ResolveConstField(typeInst, NULL, fieldDef);			
 		}
 		
-		if (fieldDef->mInitializer == NULL)
+		if (fieldDef->GetInitializer() == NULL)
 		{
 			if (BfNodeIsA<BfVarTypeReference>(fieldDef->mTypeRef))
-			{
-				if (fieldDef->mInitializer == NULL)
-				{
-					if ((fieldDef->mTypeRef->IsA<BfVarTypeReference>()) || (fieldDef->mTypeRef->IsA<BfLetTypeReference>()))
-						mPassInstance->Fail("Implicitly-typed fields must be initialized", fieldDef->GetRefNode());
-				}
+			{				
+				if ((fieldDef->mTypeRef->IsA<BfVarTypeReference>()) || (fieldDef->mTypeRef->IsA<BfLetTypeReference>()))
+					mPassInstance->Fail("Implicitly-typed fields must be initialized", fieldDef->GetRefNode());				
 			}
 		}
 	}
@@ -4613,17 +4611,19 @@ void BfCompiler::ProcessAutocompleteTempType()
 	}
 	
  	for (auto propDef : tempTypeDef->mProperties)
-	{		
-		if ((propDef->mFieldDeclaration != NULL) && (propDef->mFieldDeclaration->mAttributes != NULL))
+	{	
+		auto fieldDecl = propDef->GetFieldDeclaration();
+
+		if ((fieldDecl != NULL) && (fieldDecl->mAttributes != NULL))
 		{
 			BfAttributeTargets target = BfAttributeTargets_Property;
 			if (propDef->IsExpressionBodied())
 				target = (BfAttributeTargets)(target | BfAttributeTargets_Method);
-			auto customAttrs = module->GetCustomAttributes(propDef->mFieldDeclaration->mAttributes, target);
+			auto customAttrs = module->GetCustomAttributes(fieldDecl->mAttributes, target);
 			delete customAttrs;
 		}
 		
-		auto propDeclaration = BfNodeDynCast<BfPropertyDeclaration>(propDef->mFieldDeclaration);
+		auto propDeclaration = BfNodeDynCast<BfPropertyDeclaration>(fieldDecl);
 		if (propDeclaration != NULL)
 			autoComplete->CheckProperty(propDeclaration);
 		module->ResolveTypeRef(propDef->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowRef);
@@ -4636,7 +4636,7 @@ void BfCompiler::ProcessAutocompleteTempType()
 			}
 		}
 
-		if ((autoComplete->mIsGetDefinition) && (propDef->mFieldDeclaration != NULL) && (autoComplete->IsAutocompleteNode(propDef->mFieldDeclaration->mNameNode)))
+		if ((autoComplete->mIsGetDefinition) && (fieldDecl != NULL) && (autoComplete->IsAutocompleteNode(fieldDecl->mNameNode)))
 		{
 			auto checkType = typeInst;
 			while (checkType != NULL)
@@ -5119,8 +5119,8 @@ void BfCompiler::GetSymbolReferences()
 				BfTypeInstance* checkTypeInst = rebuildTypeInst;
 				typeState.mCurTypeDef = propDef->mDeclaringType;
 				module->GetBasePropertyDef(checkPropDef, checkTypeInst);
-				if (propDef->mFieldDeclaration != NULL)
-					mResolvePassData->HandlePropertyReference(propDef->mFieldDeclaration->mNameNode, checkTypeInst->mTypeDef, checkPropDef);
+				if (auto fieldDecl = propDef->GetFieldDeclaration())
+					mResolvePassData->HandlePropertyReference(fieldDecl->mNameNode, checkTypeInst->mTypeDef, checkPropDef);
 			}
 		}
 
@@ -5128,10 +5128,10 @@ void BfCompiler::GetSymbolReferences()
 		{			
 			for (auto fieldDef : typeDef->mFields)
 			{
-				if (fieldDef->mFieldDeclaration != NULL)
+				if (auto nameNode = fieldDef->GetNameNode())
 				{
 					typeState.mCurTypeDef = fieldDef->mDeclaringType;
-					mResolvePassData->HandleFieldReference(fieldDef->mFieldDeclaration->mNameNode, typeDef, fieldDef);
+					mResolvePassData->HandleFieldReference(nameNode, typeDef, fieldDef);
 				}
 			}
 		}
@@ -5145,17 +5145,20 @@ void BfCompiler::GetSymbolReferences()
 				if (fieldDef->mTypeRef != NULL)
 					CheckSymbolReferenceTypeRef(module, fieldDef->mTypeRef);
 
-				if ((fieldDef->mIsConst) && (fieldDef->mInitializer != NULL))
+				if ((fieldDef->mIsConst) && (fieldDef->GetInitializer() != NULL))
 				{
 					BfMethodState methodState;
 					methodState.mTempKind = BfMethodState::TempKind_Static;
 					SetAndRestoreValue<BfMethodState*> prevMethodState(module->mCurMethodState, &methodState);					
 					BfConstResolver constResolver(module); 
-					constResolver.Resolve(fieldDef->mInitializer);
+					constResolver.Resolve(fieldDef->GetInitializer());
 				}
 
-				if ((fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mAttributes != NULL))
-					_CheckAttributes(fieldDef->mFieldDeclaration->mAttributes, fieldDef->mDeclaringType);
+				if (auto fieldDecl = fieldDef->GetFieldDeclaration())
+				{
+					if (fieldDecl->mAttributes != NULL)
+						_CheckAttributes(fieldDecl->mAttributes, fieldDef->mDeclaringType);
+				}
 			}
 		}
 

+ 1 - 1
IDEHelper/Compiler/BfConstResolver.cpp

@@ -49,7 +49,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
 			if (mModule->mContext->mCurTypeState != NULL)
 			{
 				if (mModule->mContext->mCurTypeState->mCurFieldDef != NULL)
-					initializer = mModule->mContext->mCurTypeState->mCurFieldDef->mInitializer;
+					initializer = mModule->mContext->mCurTypeState->mCurFieldDef->GetInitializer();
 				if (mModule->mContext->mCurTypeState->mCurVarInitializer != NULL)
 					initializer = mModule->mContext->mCurTypeState->mCurVarInitializer;
 				if (mModule->mContext->mCurTypeState->mArrayInitializerSize != -1)

+ 1 - 1
IDEHelper/Compiler/BfContext.cpp

@@ -1964,7 +1964,7 @@ void BfContext::UpdateRevisedTypes()
 		{
 			if (fieldDef->mIsStatic)
 				continue;
-			if (fieldDef->mInitializer != NULL)
+			if (fieldDef->GetInitializer() != NULL)
 				return false;
 		}
 

+ 11 - 10
IDEHelper/Compiler/BfDefBuilder.cpp

@@ -706,6 +706,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
 		for (auto paramDef : methodDef->mParams)
 		{
 			auto fieldDef = new BfFieldDef();
+			fieldDef->mFieldDeclaration = paramDef->mParamDeclaration;
 			fieldDef->mName = paramDef->mName;
 			while (fieldDef->mName.StartsWith("@"))
 			{
@@ -940,8 +941,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
 	{		
 		propertyDef->mName = "[]";
 	}
-	propertyDef->mTypeRef = propertyDeclaration->mTypeRef;
-	propertyDef->mInitializer = NULL;
+	propertyDef->mTypeRef = propertyDeclaration->mTypeRef;	
 	propertyDef->mFieldDeclaration = propertyDeclaration;
 	BF_ASSERT(mCurDeclaringTypeDef != NULL);
 	propertyDef->mDeclaringType = mCurDeclaringTypeDef;	
@@ -979,7 +979,6 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
 			fieldDef->mTypeRef = refTypeRef->mElementType;
 		fieldDef->mName = mCurTypeDef->GetAutoPropertyName(propertyDeclaration);		
 		fieldDef->mIdx = (int)mCurTypeDef->mFields.size();
-		fieldDef->mInitializer = propertyDeclaration->mInitializer;
 		mCurTypeDef->mFields.push_back(fieldDef);
 
 		mCurTypeDef->mSignatureHash = HashString(fieldDef->mName, mCurTypeDef->mSignatureHash + fieldDef->mNamePrefixCount);
@@ -1190,7 +1189,6 @@ void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration)
 	}
 
 	fieldDef->mIdx = (int)mCurTypeDef->mFields.size() - 1;	
-	fieldDef->mInitializer = fieldDeclaration->mInitializer;
 
 	//mCurTypeDef->mSignatureHash = HashNode(fieldDeclaration, mCurTypeDef->mSignatureHash);
 	if (mSignatureHashCtx != NULL)
@@ -2168,18 +2166,18 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
 				hasStaticField = true;
 				if (field->mFieldDeclaration != NULL)
 				{
-					if (field->mFieldDeclaration->mInitializer != NULL)
+					if (field->GetFieldDeclaration()->mInitializer != NULL)
 					{						
 						needsStaticInit = true;
 					}
-					if (field->mFieldDeclaration->mFieldDtor != NULL)
+					if (field->GetFieldDeclaration()->mFieldDtor != NULL)
 						needsStaticDtor = true;
 				}
 			}
 
 			if (field->mFieldDeclaration != NULL)
 			{
-				auto attributes = field->mFieldDeclaration->mAttributes;
+				auto attributes = field->GetFieldDeclaration()->mAttributes;
 				while (attributes != NULL)
 				{
 					if (attributes->mAttributeTypeRef != NULL)
@@ -2197,10 +2195,13 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
 		else 
 		{
 			hasNonStaticField = true;
-			if (field->mInitializer != NULL)
+			if (field->GetInitializer() != NULL)
 				needsDefaultCtor = true;
-			if ((field->mFieldDeclaration != NULL) && (field->mFieldDeclaration->mFieldDtor != NULL))
-				needsDtor = true;
+			if (auto fieldDecl = field->GetFieldDeclaration())
+			{
+				if (fieldDecl->mFieldDtor != NULL)
+					needsDtor = true;
+			}
 		}
 	}
 	

+ 1 - 1
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -4804,7 +4804,7 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe
 					}
 				}
 
-				auto fieldDecl = fieldInstance->GetFieldDef()->mFieldDeclaration;
+				auto fieldDecl = fieldInstance->GetFieldDef()->GetFieldDeclaration();
 				if ((fieldDecl != NULL) && (fieldDecl->mDocumentation != NULL))
 				{
 					String docString;

+ 56 - 40
IDEHelper/Compiler/BfModule.cpp

@@ -2300,7 +2300,7 @@ void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit)
 										continue;
 									}
 
-									if ((fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mInitializer != NULL))
+									if (fieldDef->GetInitializer() != NULL)
 									{
 										// This initializer was handled in CtorNoBody
 										foundFields = true;
@@ -4051,7 +4051,7 @@ void BfModule::CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLo
 void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfFieldDef* fieldDef, bool forceResolve)
 {
 	bool autoCompleteOnly = mCompiler->IsAutocomplete();
-	
+		
 	BfType* fieldType = NULL;
 	if (fieldInstance != NULL)
 	{
@@ -4074,7 +4074,7 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance*
 			if (isLet || isVar)
 				fieldType = GetPrimitiveType(BfTypeCode_Var);
 			else
-				fieldType = ResolveTypeRef(fieldDef->mTypeRef,BfPopulateType_Identity, BfResolveTypeRefFlag_AllowInferredSizedArray);
+				fieldType = ResolveTypeRef(fieldDef->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowInferredSizedArray);
 			if (fieldType == NULL)
 				fieldType = mContext->mBfObjectType;
 		}
@@ -4116,16 +4116,16 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance*
 		if (!fieldDef->mTypeRef->IsA<BfPointerTypeRef>())
 		{
 			SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
-			Fail("Extern consts must be pointer types", fieldDef->mFieldDeclaration->mTypeRef);
+			Fail("Extern consts must be pointer types", fieldDef->mTypeRef);
 		}
 
-		if (fieldDef->mInitializer != NULL)
+		if (fieldDef->GetInitializer() != NULL)
 		{
 			SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
-			Fail("Extern consts cannot have initializers", fieldDef->mFieldDeclaration->mNameNode);
+			Fail("Extern consts cannot have initializers", fieldDef->GetNameNode());
 		}
 	}
-	else if (fieldDef->mInitializer == NULL)
+	else if (fieldDef->GetInitializer() == NULL)
 	{
 		if (fieldDef->IsEnumCaseEntry())
 		{
@@ -4163,7 +4163,7 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance*
 		}
 		else
 		{
-			Fail("Const requires initializer", fieldDef->mFieldDeclaration->mNameNode);			
+			Fail("Const requires initializer", fieldDef->GetNameNode());
 		}
 	}
 	else if (mBfIRBuilder != NULL)
@@ -4181,7 +4181,7 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance*
 
 		if ((fieldType->IsVar()) || (fieldType->IsUndefSizedArray()))
 		{
-			auto initValue = GetFieldInitializerValue(fieldInstance, fieldDef->mInitializer, fieldDef, fieldType);
+			auto initValue = GetFieldInitializerValue(fieldInstance, fieldDef->GetInitializer(), fieldDef, fieldType);
 			if (!initValue)
 			{
 				AssertErrorState();
@@ -4203,7 +4203,7 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance*
 		}
 		else
 		{
-			auto uncastedInitValue = GetFieldInitializerValue(fieldInstance, fieldDef->mInitializer, fieldDef, fieldType);
+			auto uncastedInitValue = GetFieldInitializerValue(fieldInstance, fieldDef->GetInitializer(), fieldDef, fieldType);
 			constValue = uncastedInitValue.mValue;
 		}
 
@@ -4243,7 +4243,7 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance*
 
 BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfFieldDef* field)
 {	
-	bool isDeclType = (field->mFieldDeclaration != NULL) && BfNodeDynCastExact<BfExprModTypeRef>(field->mFieldDeclaration->mTypeRef) != NULL;
+	bool isDeclType = (field->mFieldDeclaration != NULL) && BfNodeDynCastExact<BfExprModTypeRef>(field->mTypeRef) != NULL;
 
 	auto fieldType = fieldInstance->GetResolvedType();
 	if ((field->mIsConst) && (!isDeclType))
@@ -4297,7 +4297,7 @@ BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInsta
 	SetAndRestoreValue<bool> prevResolvingVar(typeInstance->mResolvingVarField, true);	
 	SetAndRestoreValue<bool> prevCtxResolvingVar(mContext->mResolvingVarField, true);	
 	
-	if ((field->mInitializer == NULL) && (!isDeclType))
+	if ((field->GetInitializer() == NULL) && (!isDeclType))
 	{
 		if ((field->mTypeRef->IsA<BfVarTypeReference>()) || (field->mTypeRef->IsA<BfLetTypeReference>()))
 			Fail("Implicitly-typed fields must be initialized", field->GetRefNode());		
@@ -4428,7 +4428,7 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
 	{
 		if (fieldDef == NULL)
 			return BfTypedValue();
-		initializer = fieldDef->mInitializer;
+		initializer = fieldDef->GetInitializer();
 	}
 
 	BfTypedValue staticVarRef;
@@ -15194,10 +15194,18 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo
 		BF_ASSERT(rootMethodState->mCurLocalVarId >= 0);
 		localVarDef->mLocalVarId = rootMethodState->mCurLocalVarId++;
 	}
-	if ((localVarDef->mNameNode != NULL) && (mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) && (!mIsComptimeModule))
-		mCompiler->mResolvePassData->mAutoComplete->CheckLocalDef(localVarDef->mNameNode, localVarDef);
 
-	if ((localVarDef->mNameNode != NULL) && (mCurMethodInstance != NULL))
+	bool checkLocal = true;
+	if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Ctor))
+	{
+		if (auto autoCtorDecl = BfNodeDynCast<BfAutoConstructorDeclaration>(mCurMethodInstance->mMethodDef->mMethodDeclaration))
+			checkLocal = false;
+	}	
+
+	if ((localVarDef->mNameNode != NULL) && (mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) && (!mIsComptimeModule) && (checkLocal))
+		mCompiler->mResolvePassData->mAutoComplete->CheckLocalDef(localVarDef->mNameNode, localVarDef);	
+
+	if (((localVarDef->mNameNode != NULL) && (mCurMethodInstance != NULL)) && (checkLocal))
 	{		
 		bool isClosureProcessing = (mCurMethodState->mClosureState != NULL) && (!mCurMethodState->mClosureState->mCapturing);		
 		if ((!isClosureProcessing) && (mCompiler->mResolvePassData != NULL) && (localVarDef->mNameNode != NULL) && (rootMethodState->mMethodInstance != NULL) && (!mIsComptimeModule))
@@ -16616,13 +16624,13 @@ void BfModule::CreateStaticCtor()
 	{
 		for (auto fieldDef : typeDef->mFields)
 		{
-			if ((!fieldDef->mIsConst) && (fieldDef->mIsStatic) && (fieldDef->mInitializer != NULL))
+			if ((!fieldDef->mIsConst) && (fieldDef->mIsStatic) && (fieldDef->GetInitializer() != NULL))
 			{
 				// For extensions, only handle these fields in the appropriate extension
 				if ((fieldDef->mDeclaringType->mTypeDeclaration != methodDef->mDeclaringType->mTypeDeclaration))
 					continue;
 								
-				UpdateSrcPos(fieldDef->mInitializer);				
+				UpdateSrcPos(fieldDef->GetInitializer());				
 				
 				auto fieldInst = &mCurTypeInstance->mFieldInstances[fieldDef->mIdx];					
 				if (!fieldInst->mFieldIncluded)
@@ -16651,19 +16659,19 @@ void BfModule::CreateStaticCtor()
 				{
 					if ((fieldDef->mIsStatic) && (!fieldDef->mIsConst))
 					{
-						if (fieldDef->mInitializer != NULL)
+						if (fieldDef->GetInitializer() != NULL)
 						{
-							if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(fieldDef->mInitializer))
+							if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(fieldDef->GetInitializer()))
 							{
-								sourceClassifier->SetElementType(fieldDef->mInitializer, BfSourceElementType_Normal);
-								sourceClassifier->VisitChild(fieldDef->mInitializer);
+								sourceClassifier->SetElementType(fieldDef->GetInitializer(), BfSourceElementType_Normal);
+								sourceClassifier->VisitChildNoRef(fieldDef->GetInitializer());
 							}
 							BfType* wantType = NULL;
 							if ((!BfNodeIsA<BfVarTypeReference>(fieldDef->mTypeRef)) && (!BfNodeIsA<BfLetTypeReference>(fieldDef->mTypeRef)))
 							{
 								wantType = ResolveTypeRef(fieldDef->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowInferredSizedArray);
 							}							
-							CreateValueFromExpression(fieldDef->mInitializer, wantType, BfEvalExprFlags_FieldInitializer);
+							CreateValueFromExpression(fieldDef->GetInitializer(), wantType, BfEvalExprFlags_FieldInitializer);
 						}						
 					}
 				}
@@ -16745,7 +16753,9 @@ void BfModule::EmitDtorBody()
 		{
 			auto fieldInst = &mCurTypeInstance->mFieldInstances[fieldIdx];
 			auto fieldDef = fieldInst->GetFieldDef();
-			if ((fieldDef != NULL) && (fieldDef->mIsStatic == methodDef->mIsStatic) && (fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mFieldDtor != NULL))
+			auto fieldDecl = fieldDef->GetFieldDeclaration();
+
+			if ((fieldDef != NULL) && (fieldDef->mIsStatic == methodDef->mIsStatic) && (fieldDecl != NULL) && (fieldDecl->mFieldDtor != NULL))
 			{
 				if (fieldDef->mDeclaringType != mCurMethodInstance->mMethodDef->mDeclaringType)
 				{
@@ -16755,12 +16765,12 @@ void BfModule::EmitDtorBody()
 
 				if ((!methodDef->mIsStatic) && (mCurTypeInstance->IsValueType()))
 				{
-					Fail("Structs cannot have field destructors", fieldDef->mFieldDeclaration->mFieldDtor->mTildeToken, true);
+					Fail("Structs cannot have field destructors", fieldDecl->mFieldDtor->mTildeToken, true);
 				}
 
 				SetAndRestoreValue<BfFilePosition> prevFilePos(mCurFilePosition);
 
-				auto fieldDtor = fieldDef->mFieldDeclaration->mFieldDtor;
+				auto fieldDtor = fieldDecl->mFieldDtor;
 
 				if ((fieldDef->mIsStatic) != (methodDef->mIsStatic))
 					continue;
@@ -16915,8 +16925,10 @@ void BfModule::EmitDtorBody()
 			{
 				for (auto fieldDef : tempTypeDef->mFields)
 				{
+					auto fieldDecl = fieldDef->GetFieldDeclaration();
+
 					if ((fieldDef->mIsStatic == methodDef->mIsStatic) && (fieldDef->mFieldDeclaration != NULL) && 
-						(fieldDef->mFieldDeclaration->mFieldDtor != NULL) && (mCompiler->mResolvePassData->mIsClassifying))
+						(fieldDecl->mFieldDtor != NULL) && (mCompiler->mResolvePassData->mIsClassifying))
 					{
 						BfType* fieldType = NULL;
 
@@ -16930,7 +16942,7 @@ void BfModule::EmitDtorBody()
 						if (fieldType == NULL)
 							fieldType = GetPrimitiveType(BfTypeCode_Var);
 						
-						auto fieldDtor = fieldDef->mFieldDeclaration->mFieldDtor;
+						auto fieldDtor = fieldDecl->mFieldDtor;
 
 						BfScopeData scopeData;
 						mCurMethodState->AddScope(&scopeData);						
@@ -17595,8 +17607,9 @@ void BfModule::EmitCtorBody(bool& skipBody)
 						continue;
 					if (fieldInst->mDataIdx < 0)
 						continue;
+					auto initializer = fieldDef->GetInitializer();
 
-					if (fieldDef->mInitializer == NULL)
+					if (initializer == NULL)
 					{
 						continue;
 
@@ -17612,9 +17625,9 @@ void BfModule::EmitCtorBody(bool& skipBody)
 						continue;
 					}
 
-					if (fieldDef->mInitializer != NULL)
+					if (initializer != NULL)
 					{
-						_CheckInitBlock(fieldDef->mInitializer);
+						_CheckInitBlock(initializer);
 					}
 
 					BfIRValue fieldAddr;
@@ -17668,12 +17681,14 @@ void BfModule::EmitCtorBody(bool& skipBody)
 				{
 					for (auto fieldDef : tempTypeDef->mFields)
 					{
-						if ((!fieldDef->mIsStatic) && (fieldDef->mInitializer != NULL) && (mCompiler->mResolvePassData->mIsClassifying))
+						auto initializer = fieldDef->GetInitializer();						
+
+						if ((!fieldDef->mIsStatic) && (initializer != NULL) && (mCompiler->mResolvePassData->mIsClassifying))
 						{
-							if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(fieldDef->mInitializer))
+							if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(initializer))
 							{
-								sourceClassifier->SetElementType(fieldDef->mInitializer, BfSourceElementType_Normal);
-								sourceClassifier->VisitChild(fieldDef->mInitializer);
+								sourceClassifier->SetElementType(initializer, BfSourceElementType_Normal);
+								sourceClassifier->VisitChild(initializer);
 							}
 
 							BfType* wantType = NULL;
@@ -17683,7 +17698,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
 							if ((wantType != NULL) &&
 								((wantType->IsVar()) || (wantType->IsLet()) || (wantType->IsRef())))
 								wantType = NULL;
-							CreateValueFromExpression(fieldDef->mInitializer, wantType, BfEvalExprFlags_FieldInitializer);
+							CreateValueFromExpression(initializer, wantType, BfEvalExprFlags_FieldInitializer);
 						}
 					}
 
@@ -17708,10 +17723,10 @@ void BfModule::EmitCtorBody(bool& skipBody)
 			// Mark fields from full type with initializers as initialized, to give proper initialization errors within ctor
 			for (auto fieldDef : typeDef->mFields)
 			{
-				if ((!fieldDef->mIsConst) && (!fieldDef->mIsStatic) && (fieldDef->mInitializer != NULL))
+				if ((!fieldDef->mIsConst) && (!fieldDef->mIsStatic) && (fieldDef->GetInitializer() != NULL))
 				{
 					auto fieldInst = &mCurTypeInstance->mFieldInstances[fieldDef->mIdx];
-					if (fieldDef->mInitializer != NULL)
+					if (fieldDef->GetInitializer() != NULL)
 						MarkFieldInitialized(fieldInst);
 				}
 			}
@@ -18022,8 +18037,9 @@ void BfModule::EmitEnumToStringBody()
 			continue;
 
 		// Only allow compact 'ValA, ValB' enum declaration fields through
-		auto fieldDecl = fieldInstance.GetFieldDef()->mFieldDeclaration;
-		if ((fieldDecl == NULL) || (fieldDecl->mTypeRef != NULL))
+		auto fieldDef = fieldInstance.GetFieldDef();
+		auto fieldDecl = fieldDef->mFieldDeclaration;
+		if ((fieldDecl == NULL) || (fieldDef->mTypeRef != NULL))
 			continue;
 
 		auto constant = mCurTypeInstance->mConstHolder->GetConstantById(fieldInstance.mConstIdx);

+ 28 - 18
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -821,8 +821,9 @@ void BfModule::CheckMemberNames(BfTypeInstance* typeInst)
 			memberRef.mProtection = prop->mProtection;
 			memberRef.mName = prop->mName;
 			memberRef.mKindName = "property";
-			if (prop->mFieldDeclaration != NULL)
-				memberRef.mNameNode = prop->mFieldDeclaration->mNameNode;
+			auto fieldDecl = prop->GetFieldDeclaration();
+			if (fieldDecl != NULL)
+				memberRef.mNameNode = fieldDecl->mNameNode;
 			memberRef.mDeclaringType = prop->mDeclaringType;
 			auto propertyDeclaration = BfNodeDynCast<BfPropertyDeclaration>(prop->mFieldDeclaration);
 			if (propertyDeclaration != NULL)
@@ -843,11 +844,16 @@ void BfModule::CheckMemberNames(BfTypeInstance* typeInst)
 			memberRef.mName = field->mName;
 			memberRef.mKindName = "field";
 			memberRef.mDeclaringType = field->mDeclaringType;
-			if (field->mFieldDeclaration != NULL)
+			if (auto fieldDecl = field->GetFieldDeclaration())
 			{
-				memberRef.mNameNode = field->mFieldDeclaration->mNameNode;
-				memberRef.mIsOverride = field->mFieldDeclaration->mNewSpecifier != NULL;
+				memberRef.mNameNode = fieldDecl->mNameNode;
+				memberRef.mIsOverride = fieldDecl->mNewSpecifier != NULL;
 			}
+			else if (auto paramDecl = field->GetParamDeclaration())
+			{
+				memberRef.mNameNode = paramDecl->mNameNode;
+			}
+
 			memberList.push_back(memberRef);
 		}
 
@@ -1045,7 +1051,7 @@ bool BfModule::CheckCircularDataError()
 		else if ((checkTypeState->mCurFieldDef != NULL) && (checkTypeState->mCurFieldDef->mFieldDeclaration != NULL))
 		{
 			Fail(StrFormat("Field '%s.%s' causes a data cycle", TypeToString(checkTypeState->mType).c_str(), checkTypeState->mCurFieldDef->mName.c_str()),
-				checkTypeState->mCurFieldDef->mFieldDeclaration->mTypeRef, true);
+				checkTypeState->mCurFieldDef->mTypeRef, true);
 		}
 		else if (checkTypeState->mCurFieldDef != NULL)
 		{
@@ -4387,7 +4393,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 				SetAndRestoreValue<BfTypeState::ResolveKind> prevResolveKind(mContext->mCurTypeState->mResolveKind, BfTypeState::ResolveKind_FieldType);
 				
 				BfType* resolvedFieldType = NULL;
-				
+								
+				auto initializer = field->GetInitializer();
+
 				if (field->IsEnumCaseEntry())
 				{
 					if (typeInstance->IsEnum())
@@ -4432,7 +4440,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 				else
 				{	
 					BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_NoResolveGenericParam;
-					if (field->mInitializer != NULL)
+					if (initializer != NULL)
 						resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowInferredSizedArray);
 					resolvedFieldType = ResolveTypeRef(field->mTypeRef, BfPopulateType_Declaration, resolveFlags);
 					if (resolvedFieldType == NULL)
@@ -4449,7 +4457,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 					{
 						if (arrayTypeRef->IsInferredSize())
 						{
-							if (field->mInitializer != NULL)
+							if (initializer != NULL)
 							{
 								DeferredResolveEntry resolveEntry;
 								resolveEntry.mFieldDef = field;
@@ -4523,7 +4531,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 			{
 				// Already handled
 			}
-			else if ((fieldDef != NULL) && (fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mAttributes != NULL) && (!typeInstance->mTypeFailed))
+			else if ((fieldDef != NULL) && (fieldDef->GetFieldDeclaration() != NULL) && (fieldDef->GetFieldDeclaration()->mAttributes != NULL) && (!typeInstance->mTypeFailed))
 			{
 				if (auto propDecl = BfNodeDynCast<BfPropertyDeclaration>(fieldDef->mFieldDeclaration))
 				{
@@ -4533,14 +4541,14 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 				{
 					SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef);
 					
-					fieldInstance->mCustomAttributes = GetCustomAttributes(fieldDef->mFieldDeclaration->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
+					fieldInstance->mCustomAttributes = GetCustomAttributes(fieldDef->GetFieldDeclaration()->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
 					for (auto customAttr : fieldInstance->mCustomAttributes->mAttributes)
 					{
 						if (TypeToString(customAttr.mType) == "System.ThreadStaticAttribute")
 						{
 							if ((!fieldDef->mIsStatic) || (fieldDef->mIsConst))
 							{
-								Fail("ThreadStatic attribute can only be used on static fields", fieldDef->mFieldDeclaration->mAttributes);
+								Fail("ThreadStatic attribute can only be used on static fields", fieldDef->GetFieldDeclaration()->mAttributes);
 							}
 						}
 					}
@@ -4750,9 +4758,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 				if (propDef->IsExpressionBodied())
 					target = (BfAttributeTargets)(target | BfAttributeTargets_Method);
 
-				if ((propDef->mFieldDeclaration->mAttributes != NULL) && (!typeInstance->mTypeFailed))
+				if ((propDef->GetFieldDeclaration()->mAttributes != NULL) && (!typeInstance->mTypeFailed))
 				{
-					auto customAttrs = GetCustomAttributes(propDef->mFieldDeclaration->mAttributes, target);
+					auto customAttrs = GetCustomAttributes(propDef->GetFieldDeclaration()->mAttributes, target);
 					delete customAttrs;
 				}
 
@@ -4845,7 +4853,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 				if ((!typeInstance->IsBoxed()) && (fieldDef != NULL))
 				{
 					if ((fieldDef->mUsingProtection != BfProtection_Hidden) && (!resolvedFieldType->IsStruct()) && (!resolvedFieldType->IsObject()))
-						Warn(0, StrFormat("Field type '%s' is not applicable for 'using'", TypeToString(resolvedFieldType).c_str()), fieldDef->mFieldDeclaration->mConstSpecifier);
+						Warn(0, StrFormat("Field type '%s' is not applicable for 'using'", TypeToString(resolvedFieldType).c_str()), fieldDef->GetFieldDeclaration()->mConstSpecifier);
 
 					if (fieldInstance->mIsEnumPayloadCase)
 					{						
@@ -4871,12 +4879,14 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 
 						if (fieldDef->mIsExtern)
 						{
-							Fail("Cannot declare instance member as 'extern'", fieldDef->mFieldDeclaration->mExternSpecifier, true);
+							Fail("Cannot declare instance member as 'extern'", fieldDef->GetFieldDeclaration()->mExternSpecifier, true);
 						}
 
 						BfAstNode* nameRefNode = NULL;
-						if (fieldDef->mFieldDeclaration != NULL)
-							nameRefNode = fieldDef->mFieldDeclaration->mNameNode;
+						if (auto fieldDecl = fieldDef->GetFieldDeclaration())
+							nameRefNode = fieldDecl->mNameNode;
+						else if (auto paramDecl = fieldDef->GetParamDeclaration())
+							nameRefNode = paramDecl->mNameNode;
 						if (nameRefNode == NULL)
 							nameRefNode = fieldDef->mTypeRef;
 

+ 9 - 2
IDEHelper/Compiler/BfSystem.cpp

@@ -3244,8 +3244,15 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef)
 
 		for (auto fieldDef : partialTypeDef->mFields)
 		{
-			if ((!fieldDef->mIsStatic) && (fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mInitializer != NULL))
-				hasInitializers = true;
+			if (!fieldDef->mIsStatic) 
+			{
+				if (auto fieldDeclaration = BfNodeDynCast<BfFieldDeclaration>(fieldDef->mFieldDeclaration))
+					if (fieldDeclaration->mInitializer != NULL)					
+						hasInitializers = true;
+				if (auto paramDeclaration = BfNodeDynCast<BfParameterDeclaration>(fieldDef->mFieldDeclaration))
+					if (paramDeclaration->mInitializer != NULL)
+						hasInitializers = true;
+			}
 		}
 
 		if (hasInitializers)

+ 45 - 8
IDEHelper/Compiler/BfSystem.h

@@ -564,14 +564,13 @@ class BfFieldDef : public BfMemberDef
 public:
 	int mIdx;	
 	bool mIsConst; // Note: Consts are also all considered Static		
+	BfTypeReference* mTypeRef;
 	BfProtection mUsingProtection;
 	bool mIsInline;
 	bool mIsVolatile;
 	bool mIsExtern;	
-	bool mIsProperty;
-	BfTypeReference* mTypeRef;	
-	BfExpression* mInitializer;
-	BfFieldDeclaration* mFieldDeclaration;
+	bool mIsProperty;	
+	BfAstNode* mFieldDeclaration;
 	// It may seem that fields and properties don't need a 'mNextWithSameName', but with extensions it's possible
 	//  to have two libraries which each add a field to a type with the same name	
 	BfFieldDef* mNextWithSameName;
@@ -581,13 +580,12 @@ public:
 	{
 		mIdx = 0;
 		mIsConst = false;		
+		mTypeRef = NULL;
 		mUsingProtection = BfProtection_Hidden;
 		mIsInline = false;
 		mIsExtern = false;
 		mIsVolatile = false;
 		mIsProperty = false;
-		mTypeRef = NULL;
-		mInitializer = NULL;
 		mFieldDeclaration = NULL;
 		mNextWithSameName = NULL;
 	}
@@ -611,10 +609,49 @@ public:
 	{
 		if (mFieldDeclaration == NULL)
 			return NULL;
-		if (mFieldDeclaration->mNameNode != NULL)
-			return mFieldDeclaration->mNameNode;
+
+		if (auto fieldDeclaration = BfNodeDynCast<BfFieldDeclaration>(mFieldDeclaration))
+		{
+			if (fieldDeclaration->mNameNode != NULL)
+				return fieldDeclaration->mNameNode;
+		}
+
+		if (auto paramDeclaration = BfNodeDynCast<BfParameterDeclaration>(mFieldDeclaration))
+		{
+			if (paramDeclaration->mNameNode != NULL)
+				return paramDeclaration->mNameNode;
+		}
+
 		return mFieldDeclaration;
 	}
+
+	BfFieldDeclaration* GetFieldDeclaration()
+	{
+		return BfNodeDynCast<BfFieldDeclaration>(mFieldDeclaration);
+	}
+
+	BfParameterDeclaration* GetParamDeclaration()
+	{
+		return BfNodeDynCast<BfParameterDeclaration>(mFieldDeclaration);
+	}
+
+	BfExpression* GetInitializer()
+	{
+		if (auto fieldDecl = GetFieldDeclaration())
+			return fieldDecl->mInitializer;
+		if (auto paramDecl = GetParamDeclaration())
+			return paramDecl->mInitializer;
+		return NULL;
+	}
+	
+	BfAstNode* GetNameNode()
+	{
+		if (auto fieldDecl = GetFieldDeclaration())
+			return fieldDecl->mNameNode;
+		if (auto paramDecl = GetParamDeclaration())
+			return paramDecl->mNameNode;
+		return NULL;
+	}
 };
 
 class BfPropertyDef : public BfFieldDef