// 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; } } }