Files
UnrealEngineUWP/Engine/Source/Programs/UnrealHeaderTool/Private/HeaderParser.h
Tim Smith 3cf40f7cff Removing engine types from C++ UHT.
C++ UHT can no longer run external script generators but can still be used to validate C# UHT.

#rb self
#preflight 63ca8cb06a00f3cc8ee8b943

[CL 23788618 by Tim Smith in ue5-main branch]
2023-01-20 07:56:59 -05:00

717 lines
26 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "ParserHelper.h"
#include "BaseParser.h"
#include "Scope.h"
#include "UnrealTypeDefinitionInfo.h"
#include "GeneratedCodeVersion.h"
#include "ClassMaps.h"
#include "RigVMDefines.h"
class UClass;
enum class EGeneratedCodeVersion : uint8;
class FFeedbackContext;
class UPackage;
struct FManifestModule;
class FStringOutputDevice;
class FUnrealSourceFile;
class FScope;
class FHeaderProvider;
struct FDeclaration;
/*-----------------------------------------------------------------------------
Constants & types.
-----------------------------------------------------------------------------*/
enum {MAX_NEST_LEVELS = 16};
/* Code nesting types. */
enum class ENestType
{
GlobalScope,
Class,
FunctionDeclaration,
Interface,
NativeInterface
};
/** Types of statements to allow within a particular nesting block. */
enum class ENestAllowFlags
{
None = 0,
Function = 1, // Allow Event declarations at this level.
VarDecl = 2, // Allow variable declarations at this level.
Class = 4, // Allow class definition heading.
Return = 8, // Allow 'return' within a function.
TypeDecl = 16, // Allow declarations which do not affect memory layout, such as structs, enums, and consts, but not implicit delegates
ImplicitDelegateDecl = 32, // Allow implicit delegates (i.e. those not decorated with UDELEGATE) to be declared
};
ENUM_CLASS_FLAGS(ENestAllowFlags)
/** Options for GetVarType method */
enum class EGetVarTypeOptions
{
None = 0,
OuterTypeDeprecated = 1, // Containing type has been deprecated
NoAutoConst = 2, // Don't automatically mark properties as CPF_Const
};
ENUM_CLASS_FLAGS(EGetVarTypeOptions)
namespace EDelegateSpecifierAction
{
enum Type
{
DontParse,
Parse
};
}
enum class ELayoutMacroType
{
None = -1,
Array,
ArrayEditorOnly,
Bitfield,
BitfieldEditorOnly,
Field,
FieldEditorOnly,
FieldInitialized,
};
/** Information for a particular nesting level. */
class FNestInfo
{
/** Link to the stack node. */
FScope* Scope;
public:
/**
* Gets nesting scope.
*/
FScope* GetScope() const
{
return Scope;
}
/**
* Sets nesting scope.
*/
void SetScope(FScope* InScope)
{
this->Scope = InScope;
}
/** Statement that caused the nesting. */
ENestType NestType;
/** Types of statements to allow at this nesting level. */
ENestAllowFlags Allow;
};
struct FIndexRange
{
int32 StartIndex;
int32 Count;
};
#ifndef UHT_DOCUMENTATION_POLICY_DEFAULT
#define UHT_DOCUMENTATION_POLICY_DEFAULT false
#endif
struct FDocumentationPolicy
{
bool bClassOrStructCommentRequired = UHT_DOCUMENTATION_POLICY_DEFAULT;
bool bFunctionToolTipsRequired = UHT_DOCUMENTATION_POLICY_DEFAULT;
bool bMemberToolTipsRequired = UHT_DOCUMENTATION_POLICY_DEFAULT;
bool bParameterToolTipsRequired = UHT_DOCUMENTATION_POLICY_DEFAULT;
bool bFloatRangesRequired = UHT_DOCUMENTATION_POLICY_DEFAULT;
};
/////////////////////////////////////////////////////
// FHeaderParser
//
// Header parser class. Extracts metadata from annotated C++ headers and gathers enough
// information to autogenerate additional headers and other boilerplate code.
//
class FHeaderParser : public FBaseParser
{
friend class FRecordTokens;
public:
// Performs a preliminary parse of the text in the specified buffer, pulling out:
// Class name and parent class name
// Is it an interface
// The list of other classes/interfaces it is dependent on
//
// It also splits the buffer up into:
// ScriptText (text outside of #if CPP and #if DEFAULTS blocks)
static void SimplifiedClassParse(FUnrealSourceFile& SourceFile, const TCHAR* Buffer, FStringOutputDevice& ScriptText);
/**
* Returns True if the given class name includes a valid Unreal prefix and matches up with the given original class Name.
*
* @param InNameToCheck - Name w/ potential prefix to check
* @param OriginalClassName - Name of class w/ no prefix to check against
*/
static bool ClassNameHasValidPrefix(const FString& InNameToCheck, const FString& OriginalClassName);
/**
* Parse the given header.
*
* @param PackDef The owning package of the source
* @param SourceFile The source file being parsed
*/
static void Parse(FUnrealPackageDefinitionInfo& PackageDef, FUnrealSourceFile& SourceFile);
protected:
friend struct FScriptLocation;
friend struct FNativeClassHeaderGenerator;
// Filename currently being parsed
const FString Filename;
// Was the first include in the file a validly formed auto-generated header include?
bool bSpottedAutogeneratedHeaderInclude = false;
// Current nest level, starts at 0.
int32 NestLevel = 0;
// Top nesting level.
FNestInfo* TopNest = nullptr;
/**
* Gets current nesting scope.
*/
FScope* GetCurrentScope() const
{
return TopNest->GetScope();
}
/**
* Tells if parser is currently in a class.
*/
bool IsInAClass() const
{
int32 Index = 0;
while (TopNest[Index].NestType != ENestType::GlobalScope)
{
if (TopNest[Index].NestType == ENestType::Class || TopNest->NestType == ENestType::Interface || TopNest->NestType == ENestType::NativeInterface)
{
return true;
}
--Index;
}
return false;
}
/**
* Gets current class definition.
*/
FUnrealClassDefinitionInfo& GetCurrentClassDef() const
{
check(TopNest->NestType == ENestType::Class || TopNest->NestType == ENestType::Interface || TopNest->NestType == ENestType::NativeInterface);
return UHTCastChecked<FUnrealClassDefinitionInfo>(static_cast<FStructScope*>(TopNest->GetScope())->GetStructDef());
}
// Information about all nesting levels.
FNestInfo Nest[MAX_NEST_LEVELS];
// enum for complier directives used to build up the directive stack
struct ECompilerDirective
{
enum Type
{
// this directive is insignificant and does not change the code generation at all
Insignificant = 0,
// this indicates we are in a WITH_EDITOR #if-Block
WithEditor = 1<<0,
// this indicates we are in a WITH_EDITORONLY_DATA #if-Block
WithEditorOnlyData = 1<<1,
};
};
/**
* Compiler directive nest in which the parser currently is
* NOTE: compiler directives are combined when more are added onto the stack, so
* checking the only the top of stack is enough to determine in which #if-Block(s) the current code
* is.
*
* ex. Stack.Num() == 1 while entering #if WITH_EDITOR:
* CompilerDirectiveStack[1] == CompilerDirectiveStack[0] | ECompilerDirective::WithEditor ==
* CompilerDirecitveStack[1] == CompilerDirectiveStack.Num()-1 | ECompilerDirective::WithEditor
*
* ex. Stack.Num() == 2 while entering #if WITH_EDITOR:
* CompilerDirectiveStack[3] == CompilerDirectiveStack[0] | CompilerDirectiveStack[1] | CompilerDirectiveStack[2] | ECompilerDirective::WithEditor ==
* CompilerDirecitveStack[3] == CompilerDirectiveStack.Num()-1 | ECompilerDirective::WithEditor
*/
TArray<uint32> CompilerDirectiveStack;
// Return the top level compiler directive state
uint32 GetCurrentCompilerDirective() const
{
return CompilerDirectiveStack.IsEmpty() ? 0 : CompilerDirectiveStack.Last();
}
// Pushes the Directive specified to the CompilerDirectiveStack according to the rules described above
void PushCompilerDirective(ECompilerDirective::Type Directive)
{
CompilerDirectiveStack.Push(Directive | GetCurrentCompilerDirective());
}
// Removes the top most compiler directive stack entry
void PopCompilerDirective()
{
if (CompilerDirectiveStack.Num() < 1)
{
Throwf(TEXT("Unmatched '#endif' in class or global scope"));
}
CompilerDirectiveStack.Pop();
}
/**
* The starting class flags (i.e. the class flags that were set before the
* CLASS_RecompilerClear mask was applied) for the class currently being compiled
*/
uint32 PreviousClassFlags;
// For new-style classes, used to keep track of an unmatched {} pair
bool bEncounteredNewStyleClass_UnmatchedBrackets;
// Indicates that UCLASS/USTRUCT/UINTERFACE has already been parsed in this .h file..
bool bHaveSeenUClass;
// Indicates that a GENERATED_UCLASS_BODY or GENERATED_BODY has been found in the UClass.
bool bClassHasGeneratedBody;
// Indicates that a GENERATED_UINTERFACE_BODY has been found in the UClass.
bool bClassHasGeneratedUInterfaceBody;
// Indicates that a GENERATED_IINTERFACE_BODY has been found in the UClass.
bool bClassHasGeneratedIInterfaceBody;
// public, private, etc at the current parse spot
EAccessSpecifier CurrentAccessSpecifier;
////////////////////////////////////////////////////
// List of all used identifiers for net service function declarations (every function must be unique)
TMap<int32, FString> UsedRPCIds;
// List of all net service functions with undeclared response functions
TMap<int32, FString> RPCsNeedingHookup;
// Constructor.
explicit FHeaderParser(FUnrealPackageDefinitionInfo& InPackageDef, FUnrealSourceFile& InSourceFile);
// Returns true if the token is a dynamic delegate declaration
bool IsValidDelegateDeclaration(const FToken& Token) const;
// Returns true if the current token is a bitfield type
bool IsBitfieldProperty(ELayoutMacroType LayoutMacroType);
// Parse the parameter list of a function or delegate declaration
void ParseParameterList(FUnrealFunctionDefinitionInfo& FunctionDef, bool bExpectCommaBeforeName = false, TMap<FName, FString>* MetaData = NULL, EGetVarTypeOptions Options = EGetVarTypeOptions::None);
public:
// Throws if a specifier value wasn't provided
static void RequireSpecifierValue(const FUHTMessageProvider& Context, const FPropertySpecifier& Specifier, bool bRequireExactlyOne = false);
static FString RequireExactlyOneSpecifierValue(const FUHTMessageProvider& Context, const FPropertySpecifier& Specifier);
/**
* Find a field in the specified context. Starts with the specified scope, then iterates
* through the Outer chain until the field is found.
*
* @param InScope scope to start searching for the field in
* @param InIdentifier name of the field we're searching for
* @param bIncludeParents whether to allow searching in the scope of a parent struct
* @param FieldClass class of the field to search for. used to e.g. search for functions only
* @param Thing hint text that will be used in the error message if an error is encountered
*
* @return a pointer to a UField with a name matching InIdentifier, or NULL if it wasn't found
*/
static FUnrealFunctionDefinitionInfo* FindFunction(const FUnrealStructDefinitionInfo& InScope, const TCHAR* InIdentifier, bool bIncludeParents = true, const TCHAR* Thing = nullptr);
static FUnrealPropertyDefinitionInfo* FindProperty(const FUnrealStructDefinitionInfo& InScope, const TCHAR* InIdentifier, bool bIncludeParents = true, const TCHAR* Thing = nullptr);
// Checks ToValidate to make sure that its associated sparse class data struct, if one exists, is a valid structure to use for storing sparse class data.
static void CheckSparseClassData(const FUnrealStructDefinitionInfo& StructDef);
// Validates that ClassFlags are set appropriately
static void ValidateClassFlags(const FUnrealClassDefinitionInfo& ToValidate);
protected:
//@TODO: Remove this method
static void ParseClassName(const TCHAR* Temp, FString& ClassName);
/**
* @param Input An input string, expected to be a script comment.
* @return The input string, reformatted in such a way as to be appropriate for use as a tooltip.
*/
static FString FormatCommentForToolTip(const FString& Input);
/**
* Retrieves parameter comments / tooltips from the function comment
* @param Input An input string, expected to be a script comment.
* @return The map of parameter name to comment per parameter
*/
static TMap<FName, FString> GetParameterToolTipsFromFunctionComment(const FString& Input);
// High-level compiling functions.
/**
* Parses given source file.
*
* @returns Compilation result enum.
*/
void ParseHeader();
void CompileDirective();
FUnrealEnumDefinitionInfo& CompileEnum();
FUnrealScriptStructDefinitionInfo& CompileStructDeclaration();
bool CompileDeclaration(TArray<FUnrealFunctionDefinitionInfo*>& DelegatesToFixup, FToken& Token);
/** Skip C++ (noexport) declaration. */
bool SkipDeclaration(FToken& Token);
/** Similar to MatchSymbol() but will return to the exact location as on entry if the symbol was not found. */
bool SafeMatchSymbol(const TCHAR Match);
FUnrealClassDefinitionInfo& ParseClassNameDeclaration(FString& DeclaredClassName, FString& RequiredAPIMacroIfPresent);
/** The property style of a variable declaration being parsed */
struct EPropertyDeclarationStyle
{
enum Type
{
None,
UPROPERTY
};
};
/**
* Resets current class data back to its defaults.
*/
void ResetClassData();
/**
* Create new function object based on given info structure.
*/
FUnrealFunctionDefinitionInfo& CreateFunction(const TCHAR* FuncName, FFuncInfo&& FuncInfo, EFunctionType InFunctionType) const;
FUnrealClassDefinitionInfo& CompileClassDeclaration();
FUnrealFunctionDefinitionInfo& CompileDelegateDeclaration(const FStringView& DelegateIdentifier, EDelegateSpecifierAction::Type SpecifierAction = EDelegateSpecifierAction::DontParse);
FUnrealFunctionDefinitionInfo& CompileFunctionDeclaration();
void CompileVariableDeclaration (FUnrealStructDefinitionInfo& StructDef);
void CompileInterfaceDeclaration();
void CompileRigVMMethodDeclaration(FUnrealStructDefinitionInfo& StructDef);
void ParseRigVMMethodParameters(FUnrealStructDefinitionInfo& StructDef);
FUnrealClassDefinitionInfo* ParseInterfaceNameDeclaration(FString& DeclaredInterfaceName, FString& RequiredAPIMacroIfPresent, bool bIsNativeInterface);
bool TryParseIInterfaceClass();
bool CompileStatement(TArray<FUnrealFunctionDefinitionInfo*>& DelegatesToFixup);
// Checks to see if a particular kind of command is allowed on this nesting level.
bool IsAllowedInThisNesting(ENestAllowFlags AllowFlags);
// Make sure that a particular kind of command is allowed on this nesting level.
// If it's not, issues a compiler error referring to the token and the current
// nesting level.
void CheckAllow(const TCHAR* Thing, ENestAllowFlags AllowFlags);
void SkipStatements( int32 SubCount, const TCHAR* ErrorTag );
/**
* Parses a variable or return value declaration and determines the variable type and property flags.
*
* @param Scope struct to create the property in
* @param Options options to control how the variable type is parsed
* @param VarProperty will be filled in with type and property flag data for the property declaration that was parsed
* @param Disallow contains a mask of variable modifiers that are disallowed in this context
* @param OuterPropertyType only specified when compiling the inner properties for arrays or maps.
* @param OuterPropertyFlags flags associated with the outer property being compiled.
* @param PropertyDeclarationStyle if the variable is defined with a UPROPERTY
* @param VariableCategory what kind of variable is being parsed
* @param ParsedVarIndexRange The source text [Start, End) index range for the parsed type.
*/
void GetVarType(
FScope* Scope,
EGetVarTypeOptions Options,
FPropertyBase& VarProperty,
EPropertyFlags Disallow,
EUHTPropertyType OuterPropertyType,
EPropertyFlags OuterPropertyFlags,
EPropertyDeclarationStyle::Type PropertyDeclarationStyle,
EVariableCategory VariableCategory,
FIndexRange* ParsedVarIndexRange = nullptr,
ELayoutMacroType* OutLayoutMacroType = nullptr);
/**
* Parses a variable name declaration and creates a new FProperty object.
*
* @param ParentStruct struct to create the property in
* @param VarProperty type and propertyflag info for the new property (inout)
* @param VariableCategory what kind of variable is being created
*
* @return a reference to the new property if successful, or NULL if there was no property to parse
*/
FUnrealPropertyDefinitionInfo& GetVarNameAndDim(
FUnrealStructDefinitionInfo& ParentStruct,
FPropertyBase& VarProperty,
EVariableCategory VariableCategory,
ELayoutMacroType LayoutMacroType = ELayoutMacroType::None);
/**
* Parses optional metadata text.
*
* @param MetaData the metadata map to store parsed metadata in
* @param FieldName the field being parsed (used for logging)
*
* @return true if metadata was specified
*/
void ParseFieldMetaData(TMap<FName, FString>& MetaData, const TCHAR* FieldName);
/**
* Formats the current comment, if any, and adds it to the metadata as a tooltip.
*
* @param MetaData the metadata map to store the tooltip in
*/
void AddFormattedPrevCommentAsTooltipMetaData(TMap<FName, FString>& MetaData);
/**
* Tries to parse the token as an access protection specifier (public:, protected:, or private:)
*
* @return EAccessSpecifier this is, or zero if it is none
*/
EAccessSpecifier ParseAccessProtectionSpecifier(const FToken& Token);
const TCHAR* NestTypeName( ENestType NestType );
FUnrealClassDefinitionInfo* GetQualifiedClass(const TCHAR* Thing);
/**
* Increase the nesting level, setting the new top nesting level to
* the one specified. If pushing a function or state and it overrides a similar
* thing declared on a lower nesting level, verifies that the override is legal.
*
* @param NestType the new nesting type
* @param InNode @todo
*/
void PushNest(ENestType NestType, FUnrealStructDefinitionInfo* InNodeDef, FUnrealSourceFile* SourceFile = nullptr);
void PopNest(ENestType NestType, const TCHAR* Descr);
/**
* Tasks that need to be done after popping function declaration
* from parsing stack.
*
* @param PoppedFunction Function that have just been popped.
*/
void PostPopFunctionDeclaration(FUnrealFunctionDefinitionInfo& PoppedFunctionDef);
/**
* Tasks that need to be done after popping interface definition
* from parsing stack.
*
* @param CurrentInterfaceDef Interface that have just been popped.
*/
void PostPopNestInterface(FUnrealClassDefinitionInfo& CurrentInterfaceDef);
/**
* Tasks that need to be done after popping class definition
* from parsing stack.
*
* @param CurrentClassDef Class that have just been popped.
*/
void PostPopNestClass(FUnrealClassDefinitionInfo& CurrentClassDef);
/**
* Binds all delegate properties declared in ValidationScope the delegate functions specified in the variable declaration, verifying that the function is a valid delegate
* within the current scope. This must be done once the entire class has been parsed because instance delegate properties must be declared before the delegate declaration itself.
*
* @todo: this function will no longer be required once the post-parse fixup phase is added (TTPRO #13256)
*
* @param Struct the struct to validate delegate properties for
* @param Scope the current scope
* @param DelegateCache cached map of delegates that have already been found; used for faster lookup.
*/
void FixupDelegateProperties(FUnrealStructDefinitionInfo& StructDef, FScope& Scope, TMap<FName, FUnrealFunctionDefinitionInfo*>& DelegateCache);
// Retry functions.
void InitScriptLocation( FScriptLocation& Retry );
void ReturnToLocation( const FScriptLocation& Retry, bool Binary=1, bool Text=1 );
void ValidateTypeIsDeprecated(EVariableCategory VariableCategory, FUnrealTypeDefinitionInfo* TypeDef);
void ValidatePropertyIsDeprecatedIfNecessary(bool bOuterTypeDeprecated, EVariableCategory VariableCategory, const FPropertyBase& VarProperty, EUHTPropertyType OuterPropertyType, EPropertyFlags OuterPropertyFlags);
// Cache of ScriptStructs that have been validated for Net Replication and RPC
TSet<FUnrealScriptStructDefinitionInfo*> ScriptStructsValidForNet;
/**
* Validate that a ScriptStruct is ok to be Replicated or Sent in an RPC.
*
* @param OriginStructName The Name of the ScriptStruct to check
* @param InStruct The ScriptStruct to check
*/
bool ValidateScriptStructOkForNet(const FString& OriginStructName, FUnrealScriptStructDefinitionInfo& InStructDef);
private:
// Definition of package being parsed
FUnrealPackageDefinitionInfo& PackageDef;
// True if the module currently being parsed is part of the engine, as opposed to being part of a game
bool bIsCurrentModulePartOfEngine;
/**
* Tries to match constructor parameter list. Assumes that constructor
* name is already matched.
*
* If fails it reverts all parsing done.
*
* @param Token Token to start parsing from.
*
* @returns True if matched. False otherwise.
*/
bool TryToMatchConstructorParameterList(FToken Token);
// Parses possible version declaration in generated code, e.g. GENERATED_BODY(<some_version>).
void CompileVersionDeclaration(FUnrealStructDefinitionInfo& StructDef);
// Verifies that all specified class's UProperties with function associations have valid targets
void VerifyPropertyMarkups(FUnrealClassDefinitionInfo& TargetClassDef);
// Verifies the target function meets the criteria for a blueprint property getter
void VerifyBlueprintPropertyGetter(FUnrealPropertyDefinitionInfo& PropertyDef, FUnrealFunctionDefinitionInfo* TargetFuncDef);
// Verifies the target function meets the criteria for a blueprint property setter
void VerifyBlueprintPropertySetter(FUnrealPropertyDefinitionInfo& PropertyDef, FUnrealFunctionDefinitionInfo* TargetFuncDef);
// Verifies the target function meets the criteria for a replication notify callback
void VerifyRepNotifyCallback(FUnrealPropertyDefinitionInfo& PropertyDef, FUnrealFunctionDefinitionInfo* TargetFuncDef);
// Verifies the target property meets the criteria for Getter/Setter accessor
void VerifyGetterSetterAccessorProperties(const FUnrealClassDefinitionInfo& TargetClassDef, FUnrealPropertyDefinitionInfo& PropertyDef);
// Vefifies the target property meets the criteria for FieldNotify
void VerifyNotifyValueChangedProperties(FUnrealPropertyDefinitionInfo& PropertyDef);
// Verifies that all specified class's UFunction
void VerifyFunctionsMarkups(FUnrealClassDefinitionInfo& TargetClassDef);
// Verifies the target function meets the criteria for FieldNotify
void VerifyNotifyValueChangedFunction(const FUnrealFunctionDefinitionInfo& TargetFuncDef);
// Constructs the policy from a string
static FDocumentationPolicy GetDocumentationPolicyFromName(const FUHTMessageProvider& Context, const FString& PolicyName);
// Constructs the policy for documentation checks for a given struct
static FDocumentationPolicy GetDocumentationPolicyForStruct(FUnrealStructDefinitionInfo& StructDef);
// Property types to provide UI Min and Max ranges
static TArray<FString> PropertyCPPTypesRequiringUIRanges;
// Returns true if a given CPP types required ui checking
static bool DoesCPPTypeRequireDocumentation(const FString& CPPType);
// Validates the documentation for a given enum
void CheckDocumentationPolicyForEnum(FUnrealEnumDefinitionInfo& EnumDef, const TMap<FName, FString>& MetaData, const TArray<TMap<FName, FString>>& Entries);
// Validates the documentation for a given struct
void CheckDocumentationPolicyForStruct(FUnrealStructDefinitionInfo& StructDef);
// Validates the documentation for a given method
void CheckDocumentationPolicyForFunc(FUnrealClassDefinitionInfo& ClassDef, FUnrealFunctionDefinitionInfo& FunctionDef);
// Checks if a valid range has been found on the provided metadata
bool CheckUIMinMaxRangeFromMetaData(const FString& UIMin, const FString& UIMax);
// Emits either a log message, warning, or error about a member pointer according to the behavior specified by the PointerMemberBehavior argument
void ConditionalLogPointerUsage(EPointerMemberBehavior PointerMemberBehavior, const TCHAR* PointerTypeDesc, FString&& PointerTypeDecl, const TCHAR* AlternativeTypeDesc);
// Check to see if the declaration is a constructor
static bool CheckForConstructor(FUnrealStructDefinitionInfo& StructDef, const FDeclaration& Declaration);
// Check to see if the declaration is a destructor
static bool CheckForDestructor(FUnrealStructDefinitionInfo& StructDef, const FDeclaration& Declaration);
// Check to see if the declaration is a serialize
static bool CheckForSerialize(FUnrealStructDefinitionInfo& StructDef, const FDeclaration& Declaration);
// Check to see if the declaration is a property getter function
bool CheckForPropertyGetterFunction(FUnrealStructDefinitionInfo& StructDef, const FDeclaration& Declaration);
// Check to see if the declaration is a property setter function
bool CheckForPropertySetterFunction(FUnrealStructDefinitionInfo& StructDef, const FDeclaration& Declaration);
// Names that cannot be used enums, UStructs, or UClasses
static TArray<FString> ReservedTypeNames;
public:
/**
* Checks if the given token uses one of the reserved type names.
*
* @param TypeName String of the type to check (For UObject/UClass, use the stripped name)
* @return True if the TypeName is a reserved name
*/
static bool IsReservedTypeName(const FString& TypeName);
static const FName NAME_InputText;
static const FName NAME_OutputText;
static const FName NAME_ConstantText;
static const FName NAME_VisibleText;
static const FName NAME_LazyText;
static const FName NAME_SingletonText;
static const TCHAR* TArrayText;
static const TCHAR* TEnumAsByteText;
static const TCHAR* GetRefText;
static const TCHAR* FTArrayText;
static const TCHAR* FTArrayViewText;
static const TCHAR* GetArrayText;
static const TCHAR* GetArrayViewText;
static const TCHAR* FTScriptInterfaceText;
};
/////////////////////////////////////////////////////
// FHeaderPreParser
class FHeaderPreParser : public FBaseParser
{
public:
FHeaderPreParser(FUnrealSourceFile& InSourceFile)
: FBaseParser(InSourceFile)
{
}
TSharedRef<FUnrealTypeDefinitionInfo> ParseClassDeclaration(
const TCHAR* InputText,
int32 InLineNumber,
bool bClassIsAnInterface,
const TCHAR* StartingMatchID
);
TSharedRef<FUnrealTypeDefinitionInfo> ParseEnumDeclaration(
const TCHAR* InputText,
int32 InLineNumber
);
TSharedRef<FUnrealTypeDefinitionInfo> ParseStructDeclaration(
const TCHAR* InputText,
int32 InLineNumber
);
};
class FRecordTokens
{
public:
explicit FRecordTokens(FHeaderParser& InParser, FUnrealStructDefinitionInfo* InStructDef, FToken* InToken);
~FRecordTokens();
bool Stop();
private:
FHeaderParser& Parser;
FUnrealStructDefinitionInfo* StructDef;
uint32 CurrentCompilerDirective = 0;
};