// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Text; using EpicGames.UHT.Tokenizer; namespace EpicGames.UHT.Utils { /// /// Compiler exception that immediately stops the processing of the current header file. /// public class UhtException : Exception { /// /// The generated message /// public UhtMessage UhtMessage { get; set; } /// /// Internal do nothing constructor /// protected UhtException() { } /// /// Exception with a simple message. Context will be the current header file. /// /// Text of the error public UhtException(string message) { UhtMessage = UhtMessage.MakeMessage(UhtMessageType.Error, null, null, 1, message); } /// /// Exception with a simple message. Context from the given message site. /// /// Site generating the exception /// Text of the error /// Addition context to be appended to the error message public UhtException(IUhtMessageSite messageSite, string message, object? extraContext = null) { if (extraContext != null) { message = $"{message} while parsing {UhtMessage.FormatContext(extraContext)}"; } UhtMessage = UhtMessage.MakeMessage(UhtMessageType.Error, messageSite.MessageSource, null, messageSite.GetLineNumber(), message); } /// /// Make an exception to be thrown /// /// Message site to be associated with the exception /// Line number of the error /// Text of the error /// Addition context to be appended to the error message public UhtException(IUhtMessageSite messageSite, int lineNumber, string message, object? extraContext = null) { if (extraContext != null) { message = $"{message} while parsing {UhtMessage.FormatContext(extraContext)}"; } UhtMessage = UhtMessage.MakeMessage(UhtMessageType.Error, messageSite.MessageSource, null, messageSite.GetLineNumber(lineNumber), message); } /// public override string Message => UhtMessage.Message; } /// /// Exception where the current token isn't what was expected /// public class UhtTokenException : UhtException { /// /// Make a parsing error for when there is a mismatch between the expected token and what was parsed. /// /// Message site to be associated with the exception /// The parsed token. Support for EOF also provided. /// What was expected. /// Extra context to be appended to the error message /// The exception object to throw public UhtTokenException(IUhtMessageSite messageSite, UhtToken got, object? expected, object? extraContext = null) { string message = expected != null ? $"Found {UhtMessage.FormatContext(got)} when expecting {UhtMessage.FormatContext(expected)}{FormatExtraContext(extraContext)}" : $"Found {UhtMessage.FormatContext(got)}{FormatExtraContext(extraContext)}"; UhtMessage = UhtMessage.MakeMessage(UhtMessageType.Error, messageSite.MessageSource, null, got.InputLine, message); } /// /// Format any extra context supplied by the caller or the message site /// /// Additional caller supplied context /// private static string FormatExtraContext(object? extraContext = null) { StringBuilder builder = new(" while parsing "); int startingLength = builder.Length; if (extraContext != null) { builder.Append(UhtMessage.FormatContext(extraContext)); } UhtMessage.Append(builder, UhtTlsMessageExtraContext.GetMessageExtraContext(), startingLength != builder.Length); return builder.Length != startingLength ? builder.ToString() : String.Empty; } } /// /// Internal compiler error exception /// public class UhtIceException : UhtException { /// /// Exception with a simple message. Context will be the current header file. /// /// Text of the error public UhtIceException(string message) { UhtMessage = UhtMessage.MakeMessage(UhtMessageType.Ice, null, null, 1, message); } } }