Files
UnrealEngineUWP/Engine/Source/Developer/BlueprintCompilerCppBackend/Private/BlueprintCompilerCppBackendGatherDependencies.cpp
Maciej Mroz bec08e1390 UEBP-40 C++ code generation (WIP):
- Gathering coverted class dependencies - fixed and refactored
- improved list of included headers and forward-declared structs

#codereview Mike.Beach

[CL 2681924 by Maciej Mroz in Main branch]
2015-09-06 07:59:37 -04:00

156 lines
4.3 KiB
C++

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "BlueprintCompilerCppBackendModulePrivatePCH.h"
#include "BlueprintCompilerCppBackendGatherDependencies.h"
FGatherConvertedClassDependencies::FGatherConvertedClassDependencies(UStruct* InStruct) : OriginalStruct(InStruct)
{
check(OriginalStruct);
DependenciesForHeader();
FindReferences(OriginalStruct);
}
bool FGatherConvertedClassDependencies::WillClassBeConverted(const UBlueprintGeneratedClass* InClass) const
{
// TODO:
return InClass && !InClass->HasAnyFlags(RF_ClassDefaultObject);
}
void FGatherConvertedClassDependencies::DependenciesForHeader()
{
TArray<UObject*> ObjectsToCheck;
GetObjectsWithOuter(OriginalStruct, ObjectsToCheck, true);
TArray<UObject*> NeededObjects;
FReferenceFinder HeaderReferenceFinder(NeededObjects, nullptr, false, false, true, false);
for (auto Obj : ObjectsToCheck)
{
auto Property = Cast<UProperty>(Obj);
auto OwnerProperty = IsValid(Property) ? Property->GetOwnerProperty() : nullptr;
const bool bIsParam = OwnerProperty && (0 != (OwnerProperty->PropertyFlags & CPF_Parm)) && OwnerProperty->IsIn(OriginalStruct);
const bool bIsMemberVariable = OwnerProperty && (OwnerProperty->GetOuter() == OriginalStruct);
if (bIsParam || bIsMemberVariable)
{
const UObjectProperty* ObjectProperty = Cast<UObjectProperty>(OwnerProperty);
if (ObjectProperty)
{
DeclareInHeader.Add(ObjectProperty->PropertyClass);
}
else
{
HeaderReferenceFinder.FindReferences(Obj);
}
}
}
if (auto SuperStruct = OriginalStruct->GetSuperStruct())
{
IncludeInHeader.Add(SuperStruct);
}
if (auto SourceClass = Cast<UClass>(OriginalStruct))
{
for (auto& ImplementedInterface : SourceClass->Interfaces)
{
IncludeInHeader.Add(ImplementedInterface.Class);
}
}
for (auto Obj : NeededObjects)
{
if (ShouldIncludeHeaderFor(Obj))
{
IncludeInHeader.Add(CastChecked<UField>(Obj));
}
}
}
bool FGatherConvertedClassDependencies::ShouldIncludeHeaderFor(UObject* Obj) const
{
if (Obj
&& (Obj->IsA<UClass>() || Obj->IsA<UEnum>() || Obj->IsA<UScriptStruct>())
&& !Obj->HasAnyFlags(RF_ClassDefaultObject))
{
auto ObjAsBPGC = Cast<UBlueprintGeneratedClass>(Obj);
const bool bWillBeConvetedAsBPGC = ObjAsBPGC && WillClassBeConverted(ObjAsBPGC);
const bool bRemainAsUnconvertedBPGC = ObjAsBPGC && !bWillBeConvetedAsBPGC;
if (!bRemainAsUnconvertedBPGC && (Obj->GetOutermost() != OriginalStruct->GetOutermost()))
{
return true;
}
}
return false;
}
void FGatherConvertedClassDependencies::HandleObjectReference(UObject*& InObject, const UObject* InReferencingObject, const UProperty* InReferencingProperty)
{
if (!InObject || InObject->IsA<UBlueprint>() || (InObject == OriginalStruct))
{
return;
}
auto ObjAsField = Cast<UField>(InObject);
if (ObjAsField && ShouldIncludeHeaderFor(ObjAsField) && !IncludeInHeader.Contains(ObjAsField))
{
IncludeInBody.Add(ObjAsField);
}
//TODO: What About Delegates?
auto ObjAsBPGC = Cast<UBlueprintGeneratedClass>(InObject);
const bool bWillBeConvetedAsBPGC = ObjAsBPGC && WillClassBeConverted(ObjAsBPGC);
const bool bRemainAsUnconvertedBPGC = ObjAsBPGC && !bWillBeConvetedAsBPGC;
if (bWillBeConvetedAsBPGC)
{
ConvertedClasses.Add(ObjAsBPGC);
}
else if (InObject->IsA<UUserDefinedStruct>())
{
if (!InObject->HasAnyFlags(RF_ClassDefaultObject))
{
ConvertedStructs.Add(CastChecked<UUserDefinedStruct>(InObject));
}
}
else if (InObject->IsA<UUserDefinedEnum>())
{
if (!InObject->HasAnyFlags(RF_ClassDefaultObject))
{
ConvertedEnum.Add(CastChecked<UUserDefinedEnum>(InObject));
}
}
else if (InObject->IsAsset() && !InObject->IsIn(OriginalStruct))
{
Assets.Add(InObject);
return;
}
else if (auto ObjAsClass = Cast<UClass>(InObject))
{
if (ObjAsClass->HasAnyClassFlags(CLASS_Native))
{
return;
}
}
else if (InObject->IsA<UScriptStruct>())
{
return;
}
bool AlreadyAdded = false;
SerializedObjects.Add(InObject, &AlreadyAdded);
if (!AlreadyAdded)
{
FindReferences(InObject);
}
}
void FGatherConvertedClassDependencies::FindReferences(UObject* Object)
{
{
FSimpleObjectReferenceCollectorArchive CollectorArchive(Object, *this);
CollectorArchive.SetSerializedProperty(nullptr);
CollectorArchive.SetFilterEditorOnly(true);
Object->SerializeScriptProperties(CollectorArchive);
}
Object->CallAddReferencedObjects(*this);
}