// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using EpicGames.Core;
using EpicGames.UHT.Tokenizer;
using EpicGames.UHT.Types;
using EpicGames.UHT.Utils;
namespace EpicGames.UHT.Parsers
{
///
/// Collection of parsed inheritance data
///
public struct UhtInheritance
{
///
/// Super class identifier
///
public UhtToken SuperIdentifier { get; set; } = new();
///
/// Collection of other base identifiers
///
public List BaseIdentifiers { get; } = new();
///
/// Collection of verse interface identifiers
///
public List VerseInterfaceIdentifiers { get; } = new();
///
/// Line number that the VIDENTIFIER macro appeared
///
public int VerseInterfacesLine { get; set; } = 0;
///
/// Constructor
///
public UhtInheritance()
{
}
}
///
/// Collection of helper methods
///
public static class UhtParserHelpers
{
///
/// Parse the inheritance
///
/// Header file being parsed
/// Configuration
/// Collection of inheritance information
public static void ParseInheritance(UhtHeaderFileParser headerFileParser, IUhtConfig config, out UhtInheritance inheritance)
{
// TODO: C++ UHT doesn't allow preprocessor statements inside of inheritance lists
string? restrictedPreprocessorContext = headerFileParser.RestrictedPreprocessorContext;
headerFileParser.RestrictedPreprocessorContext = "parsing inheritance list";
try
{
UhtInheritance scratch = new();
IUhtTokenReader tokenReader = headerFileParser.TokenReader;
tokenReader.Optional(':', () =>
{
tokenReader
.Require("public", "public access modifier")
.RequireIdentifier((ref UhtToken identifier) =>
{
config.RedirectTypeIdentifier(ref identifier);
scratch.SuperIdentifier = identifier;
})
.While(',', () =>
{
tokenReader
.Require("public", "public interface access specifier")
.RequireCppIdentifier(UhtCppIdentifierOptions.AllowTemplates, (UhtTokenList identifier) =>
{
scratch.BaseIdentifiers.Add(identifier.ToArray());
});
})
.Optional("VINTERFACES", () =>
{
tokenReader.Require('(');
tokenReader.RequireList(')', ',', false, () =>
{
tokenReader.RequireIdentifier((ref UhtToken identifier) =>
{
scratch.VerseInterfaceIdentifiers.Add(identifier);
});
});
scratch.VerseInterfacesLine = tokenReader.InputLine;
});
});
inheritance = scratch;
}
finally
{
headerFileParser.RestrictedPreprocessorContext = restrictedPreprocessorContext;
}
}
///
/// Parse compiler version declaration
///
/// Token reader
/// Configuration
/// Struct being parsed
public static void ParseCompileVersionDeclaration(IUhtTokenReader tokenReader, IUhtConfig config, UhtStruct structObj)
{
// Fetch the default generation code version. If supplied, then package code version overrides the default.
EGeneratedCodeVersion version = structObj.Module.Module.GeneratedCodeVersion;
if (version == EGeneratedCodeVersion.None)
{
version = config.DefaultGeneratedCodeVersion;
}
// Fetch the code version from header file
tokenReader
.Require('(')
.OptionalIdentifier((ref UhtToken identifier) =>
{
if (!Enum.TryParse(identifier.Value.ToString(), true, out version))
{
version = EGeneratedCodeVersion.None;
}
})
.Require(')');
// Save the results
structObj.GeneratedCodeVersion = version;
}
}
}