|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException;
#nullable disable
namespace Microsoft.Build.Shared
{
/// <summary>
/// This class contains methods that are useful for error checking and
/// validation of project files.
/// </summary>
/// <remarks>
/// FUTURE: This class could except an optional inner exception to put in the
/// InvalidProjectFileException, which could make debugging a host easier in some circumstances.
/// </remarks>
internal static class ProjectErrorUtilities
{
/// <summary>
/// This method is used to flag errors in the project file being processed.
/// Do NOT use this method in place of ErrorUtilities.VerifyThrow(), because
/// ErrorUtilities.VerifyThrow() is used to flag internal/programming errors.
/// </summary>
/// <param name="condition">The condition to check.</param>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
internal static void VerifyThrowInvalidProject(bool condition, IElementLocation elementLocation, string resourceName)
{
VerifyThrowInvalidProject(condition, null, elementLocation, resourceName);
}
/// <summary>
/// Overload for one string format argument.
/// </summary>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="arg0"></param>
internal static void ThrowInvalidProject<T1>(IElementLocation elementLocation, string resourceName, T1 arg0)
{
ThrowInvalidProject(null, elementLocation, resourceName, arg0);
}
/// <summary>
/// Overload for one string format argument.
/// </summary>
/// <param name="condition">The condition to check.</param>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="arg0"></param>
internal static void VerifyThrowInvalidProject<T1>(bool condition, IElementLocation elementLocation, string resourceName, T1 arg0)
{
VerifyThrowInvalidProject(condition, null, elementLocation, resourceName, arg0);
}
/// <summary>
/// Overload for two string format arguments.
/// </summary>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="arg0"></param>
/// <param name="arg1"></param>
internal static void ThrowInvalidProject<T1, T2>(IElementLocation elementLocation, string resourceName, T1 arg0, T2 arg1)
{
ThrowInvalidProject(null, elementLocation, resourceName, arg0, arg1);
}
/// <summary>
/// Overload for three string format arguments.
/// </summary>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="arg0"></param>
/// <param name="arg1"></param>
/// <param name="arg2"></param>
internal static void ThrowInvalidProject<T1, T2, T3>(IElementLocation elementLocation, string resourceName, T1 arg0, T2 arg1, T3 arg2)
{
ThrowInvalidProject(null, elementLocation, resourceName, arg0, arg1, arg2);
}
/// <summary>
/// Overload for four string format arguments.
/// </summary>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="arg0"></param>
/// <param name="arg1"></param>
/// <param name="arg2"></param>
/// <param name="arg3"></param>
internal static void ThrowInvalidProject<T1, T2, T3, T4>(IElementLocation elementLocation, string resourceName, T1 arg0, T2 arg1, T3 arg2, T4 arg3)
{
ThrowInvalidProject(null, elementLocation, resourceName, arg0, arg1, arg2, arg3);
}
/// <summary>
/// Overload for if there are more than four string format arguments.
/// </summary>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="args"></param>
internal static void ThrowInvalidProject(IElementLocation elementLocation, string resourceName, params object[] args)
{
ThrowInvalidProject(null, elementLocation, resourceName, args);
}
/// <summary>
/// Overload for two string format arguments.
/// </summary>
/// <param name="condition">The condition to check.</param>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="arg0"></param>
/// <param name="arg1"></param>
internal static void VerifyThrowInvalidProject<T1, T2>(bool condition, IElementLocation elementLocation, string resourceName, T1 arg0, T2 arg1)
{
VerifyThrowInvalidProject(condition, null, elementLocation, resourceName, arg0, arg1);
}
/// <summary>
/// Overload for three string format arguments.
/// </summary>
/// <param name="condition">The condition to check.</param>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="arg0"></param>
/// <param name="arg1"></param>
/// <param name="arg2"></param>
internal static void VerifyThrowInvalidProject<T1, T2, T3>(bool condition, IElementLocation elementLocation, string resourceName, T1 arg0, T2 arg1, T3 arg2)
{
VerifyThrowInvalidProject(condition, null, elementLocation, resourceName, arg0, arg1, arg2);
}
/// <summary>
/// Overload for four string format arguments.
/// </summary>
/// <param name="condition">The condition to check.</param>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="arg0"></param>
/// <param name="arg1"></param>
/// <param name="arg2"></param>
/// <param name="arg3"></param>
internal static void VerifyThrowInvalidProject<T1, T2, T3, T4>(bool condition, IElementLocation elementLocation, string resourceName, T1 arg0, T2 arg1, T3 arg2, T4 arg3)
{
VerifyThrowInvalidProject(condition, null, elementLocation, resourceName, arg0, arg1, arg2, arg3);
}
/// <summary>
/// This method is used to flag errors in the project file being processed.
/// Do NOT use this method in place of ErrorUtilities.VerifyThrow(), because
/// ErrorUtilities.VerifyThrow() is used to flag internal/programming errors.
/// </summary>
/// <param name="condition">The condition to check.</param>
/// <param name="errorSubCategoryResourceName">The resource string for the
/// error sub-category (can be null).</param>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
internal static void VerifyThrowInvalidProject(bool condition, string errorSubCategoryResourceName, IElementLocation elementLocation, string resourceName)
{
if (!condition)
{
ThrowInvalidProject(errorSubCategoryResourceName, elementLocation, resourceName, null);
}
}
/// <summary>
/// Overload for one string format argument.
/// </summary>
/// <param name="condition">The condition to check.</param>
/// <param name="errorSubCategoryResourceName">The resource string for the
/// error sub-category (can be null).</param>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="arg0"></param>
internal static void VerifyThrowInvalidProject<T1>(bool condition, string errorSubCategoryResourceName, IElementLocation elementLocation, string resourceName, T1 arg0)
{
if (!condition)
{
ThrowInvalidProject(errorSubCategoryResourceName, elementLocation, resourceName, arg0);
}
}
/// <summary>
/// Overload for two string format arguments.
/// </summary>
/// <param name="condition">The condition to check.</param>
/// <param name="errorSubCategoryResourceName">The resource string for the
/// error sub-category (can be null).</param>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="arg0"></param>
/// <param name="arg1"></param>
internal static void VerifyThrowInvalidProject<T1, T2>(bool condition, string errorSubCategoryResourceName, IElementLocation elementLocation, string resourceName, T1 arg0, T2 arg1)
{
if (!condition)
{
ThrowInvalidProject(errorSubCategoryResourceName, elementLocation, resourceName, arg0, arg1);
}
}
/// <summary>
/// Overload for three string format arguments.
/// </summary>
/// <param name="condition">The condition to check.</param>
/// <param name="errorSubCategoryResourceName">The resource string for the
/// error sub-category (can be null).</param>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="arg0"></param>
/// <param name="arg1"></param>
/// <param name="arg2"></param>
internal static void VerifyThrowInvalidProject<T1, T2, T3>(bool condition, string errorSubCategoryResourceName, IElementLocation elementLocation, string resourceName, T1 arg0, T2 arg1, T3 arg2)
{
if (!condition)
{
ThrowInvalidProject(errorSubCategoryResourceName, elementLocation, resourceName, arg0, arg1, arg2);
}
}
/// <summary>
/// Overload for four string format arguments.
/// </summary>
/// <param name="condition">The condition to check.</param>
/// <param name="errorSubCategoryResourceName">The resource string for the
/// error sub-category (can be null).</param>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="arg0"></param>
/// <param name="arg1"></param>
/// <param name="arg2"></param>
/// <param name="arg3"></param>
internal static void VerifyThrowInvalidProject<T1, T2, T3, T4>(bool condition, string errorSubCategoryResourceName, IElementLocation elementLocation, string resourceName, T1 arg0, T2 arg1, T3 arg2, T4 arg3)
{
if (!condition)
{
ThrowInvalidProject(errorSubCategoryResourceName, elementLocation, resourceName, arg0, arg1, arg2, arg3);
}
}
/// <summary>
/// Throws an InvalidProjectFileException using the given data.
///
/// PERF WARNING: calling a method that takes a variable number of arguments
/// is expensive, because memory is allocated for the array of arguments -- do
/// not call this method repeatedly in performance-critical scenarios
///
/// </summary>
/// <param name="errorSubCategoryResourceName">The resource string for the
/// error sub-category (can be null).</param>
/// <param name="elementLocation">The <see cref="IElementLocation"/> of the element.</param>
/// <param name="resourceName">The resource string for the error message.</param>
/// <param name="args">Extra arguments for formatting the error message.</param>
private static void ThrowInvalidProject(string errorSubCategoryResourceName, IElementLocation elementLocation, string resourceName, params object[] args)
{
ErrorUtilities.VerifyThrowInternalNull(elementLocation, nameof(elementLocation));
#if DEBUG
if (errorSubCategoryResourceName != null)
{
ResourceUtilities.VerifyResourceStringExists(errorSubCategoryResourceName);
}
ResourceUtilities.VerifyResourceStringExists(resourceName);
#endif
string errorSubCategory = errorSubCategoryResourceName is null ? null : AssemblyResources.GetString(errorSubCategoryResourceName);
string message = ResourceUtilities.FormatResourceStringStripCodeAndKeyword(out string errorCode, out string helpKeyword, resourceName, args);
throw new InvalidProjectFileException(elementLocation.File, elementLocation.Line, elementLocation.Column, 0 /* Unknown end line */, 0 /* Unknown end column */, message, errorSubCategory, errorCode, helpKeyword);
}
}
}
|