You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Add a layer of caching to avoid running msbuild as much as possible. #jira UE-109181 #rb ben.marsh #ROBOMERGE-SOURCE: CL 17102399 in //UE5/Main/... #ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v853-17066230) [CL 17102408 by jonathan adamczewski in ue5-release-engine-test branch]
870 lines
31 KiB
C#
870 lines
31 KiB
C#
// Copyright (c) Microsoft. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.Threading;
|
|
|
|
#if BUILDINGAPPXTASKS
|
|
namespace Microsoft.Build.AppxPackage.Shared
|
|
#else
|
|
namespace Microsoft.Build.Shared
|
|
#endif
|
|
{
|
|
/// <summary>
|
|
/// This class contains methods that are useful for error checking and validation.
|
|
/// </summary>
|
|
internal static class ErrorUtilities
|
|
{
|
|
/// <summary>
|
|
/// Emergency escape hatch. If a customer hits a bug in the shipped product causing an internal exception,
|
|
/// and fortuitously it happens that ignoring the VerifyThrow allows execution to continue in a reasonable way,
|
|
/// then we can give them this undocumented environment variable as an immediate workaround.
|
|
/// </summary>
|
|
private static readonly bool s_throwExceptions = String.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILDDONOTTHROWINTERNAL"));
|
|
private static readonly bool s_enableMSBuildDebugTracing = !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILDENABLEDEBUGTRACING"));
|
|
|
|
#region DebugTracing
|
|
public static void DebugTraceMessage(string category, string formatstring, params object[] parameters)
|
|
{
|
|
if (s_enableMSBuildDebugTracing)
|
|
{
|
|
if (parameters != null)
|
|
{
|
|
Trace.WriteLine(String.Format(CultureInfo.CurrentCulture, formatstring, parameters), category);
|
|
}
|
|
else
|
|
{
|
|
Trace.WriteLine(formatstring, category);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#if !BUILDINGAPPXTASKS
|
|
#region VerifyThrow -- for internal errors
|
|
|
|
/// <summary>
|
|
/// Throws InternalErrorException.
|
|
/// This is only for situations that would mean that there is a bug in MSBuild itself.
|
|
/// </summary>
|
|
internal static void ThrowInternalError(string message, params object[] args)
|
|
{
|
|
if (s_throwExceptions)
|
|
{
|
|
throw new InternalErrorException(ResourceUtilities.FormatString(message, args));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws InternalErrorException.
|
|
/// This is only for situations that would mean that there is a bug in MSBuild itself.
|
|
/// </summary>
|
|
internal static void ThrowInternalError(string message, Exception innerException, params object[] args)
|
|
{
|
|
if (s_throwExceptions)
|
|
{
|
|
throw new InternalErrorException(ResourceUtilities.FormatString(message, args), innerException);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws InternalErrorException.
|
|
/// Indicates the code path followed should not have been possible.
|
|
/// This is only for situations that would mean that there is a bug in MSBuild itself.
|
|
/// </summary>
|
|
internal static void ThrowInternalErrorUnreachable()
|
|
{
|
|
if (s_throwExceptions)
|
|
{
|
|
throw new InternalErrorException("Unreachable?");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws InternalErrorException.
|
|
/// Indicates the code path followed should not have been possible.
|
|
/// This is only for situations that would mean that there is a bug in MSBuild itself.
|
|
/// </summary>
|
|
internal static void VerifyThrowInternalErrorUnreachable(bool condition)
|
|
{
|
|
if (s_throwExceptions && !condition)
|
|
{
|
|
throw new InternalErrorException("Unreachable?");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws InternalErrorException.
|
|
/// Indicates the code path followed should not have been possible.
|
|
/// This is only for situations that would mean that there is a bug in MSBuild itself.
|
|
/// </summary>
|
|
internal static void ThrowIfTypeDoesNotImplementToString(object param)
|
|
{
|
|
#if DEBUG
|
|
// Check it has a real implementation of ToString()
|
|
if (String.Equals(param.GetType().ToString(), param.ToString(), StringComparison.Ordinal))
|
|
{
|
|
ErrorUtilities.ThrowInternalError("This type does not implement ToString() properly {0}", param.GetType().FullName);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper to throw an InternalErrorException when the specified parameter is null.
|
|
/// This should be used ONLY if this would indicate a bug in MSBuild rather than
|
|
/// anything caused by user action.
|
|
/// </summary>
|
|
/// <param name="parameter">The value of the argument.</param>
|
|
/// <param name="parameterName">Parameter that should not be null</param>
|
|
internal static void VerifyThrowInternalNull(object parameter, string parameterName)
|
|
{
|
|
if (parameter == null)
|
|
{
|
|
ThrowInternalError("{0} unexpectedly null", parameterName);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper to throw an InternalErrorException when a lock on the specified object is not already held.
|
|
/// This should be used ONLY if this would indicate a bug in MSBuild rather than
|
|
/// anything caused by user action.
|
|
/// </summary>
|
|
/// <param name="locker">The object that should already have been used as a lock.</param>
|
|
internal static void VerifyThrowInternalLockHeld(object locker)
|
|
{
|
|
#if !CLR2COMPATIBILITY
|
|
if (!Monitor.IsEntered(locker))
|
|
{
|
|
ThrowInternalError("Lock should already have been taken");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper to throw an InternalErrorException when the specified parameter is null or zero length.
|
|
/// This should be used ONLY if this would indicate a bug in MSBuild rather than
|
|
/// anything caused by user action.
|
|
/// </summary>
|
|
/// <param name="parameterValue">The value of the argument.</param>
|
|
/// <param name="parameterName">Parameter that should not be null or zero length</param>
|
|
internal static void VerifyThrowInternalLength(string parameterValue, string parameterName)
|
|
{
|
|
VerifyThrowInternalNull(parameterValue, parameterName);
|
|
|
|
if (parameterValue.Length == 0)
|
|
{
|
|
ThrowInternalError("{0} unexpectedly empty", parameterName);
|
|
}
|
|
}
|
|
|
|
public static void VerifyThrowInternalLength<T>(T[] parameterValue, string parameterName)
|
|
{
|
|
VerifyThrowInternalNull(parameterValue, parameterName);
|
|
|
|
if (parameterValue.Length == 0)
|
|
{
|
|
ThrowInternalError("{0} unexpectedly empty", parameterName);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper to throw an InternalErrorException when the specified parameter is not a rooted path.
|
|
/// This should be used ONLY if this would indicate a bug in MSBuild rather than
|
|
/// anything caused by user action.
|
|
/// </summary>
|
|
/// <param name="value">Parameter that should be a rooted path</param>
|
|
internal static void VerifyThrowInternalRooted(string value)
|
|
{
|
|
if (!Path.IsPathRooted(value))
|
|
{
|
|
ThrowInternalError("{0} unexpectedly not a rooted path", value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// This method should be used in places where one would normally put
|
|
/// an "assert". It should be used to validate that our assumptions are
|
|
/// true, where false would indicate that there must be a bug in our
|
|
/// code somewhere. This should not be used to throw errors based on bad
|
|
/// user input or anything that the user did wrong.
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <param name="unformattedMessage"></param>
|
|
internal static void VerifyThrow
|
|
(
|
|
bool condition,
|
|
string unformattedMessage
|
|
)
|
|
{
|
|
if (!condition)
|
|
{
|
|
// PERF NOTE: explicitly passing null for the arguments array
|
|
// prevents memory allocation
|
|
ThrowInternalError(unformattedMessage, null, null);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for one string format argument.
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <param name="unformattedMessage"></param>
|
|
/// <param name="arg0"></param>
|
|
internal static void VerifyThrow
|
|
(
|
|
bool condition,
|
|
string unformattedMessage,
|
|
object arg0
|
|
)
|
|
{
|
|
// PERF NOTE: check the condition here instead of pushing it into
|
|
// the ThrowInternalError() method, because that method always
|
|
// allocates memory for its variable array of arguments
|
|
if (!condition)
|
|
{
|
|
ThrowInternalError(unformattedMessage, arg0);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for two string format arguments.
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <param name="unformattedMessage"></param>
|
|
/// <param name="arg0"></param>
|
|
/// <param name="arg1"></param>
|
|
internal static void VerifyThrow
|
|
(
|
|
bool condition,
|
|
string unformattedMessage,
|
|
object arg0,
|
|
object arg1
|
|
)
|
|
{
|
|
// PERF NOTE: check the condition here instead of pushing it into
|
|
// the ThrowInternalError() method, because that method always
|
|
// allocates memory for its variable array of arguments
|
|
if (!condition)
|
|
{
|
|
ThrowInternalError(unformattedMessage, arg0, arg1);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for three string format arguments.
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <param name="unformattedMessage"></param>
|
|
/// <param name="arg0"></param>
|
|
/// <param name="arg1"></param>
|
|
/// <param name="arg2"></param>
|
|
internal static void VerifyThrow
|
|
(
|
|
bool condition,
|
|
string unformattedMessage,
|
|
object arg0,
|
|
object arg1,
|
|
object arg2
|
|
)
|
|
{
|
|
// PERF NOTE: check the condition here instead of pushing it into
|
|
// the ThrowInternalError() method, because that method always
|
|
// allocates memory for its variable array of arguments
|
|
if (!condition)
|
|
{
|
|
ThrowInternalError(unformattedMessage, arg0, arg1, arg2);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for four string format arguments.
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <param name="unformattedMessage"></param>
|
|
/// <param name="arg0"></param>
|
|
/// <param name="arg1"></param>
|
|
/// <param name="arg2"></param>
|
|
/// <param name="arg3"></param>
|
|
internal static void VerifyThrow
|
|
(
|
|
bool condition,
|
|
string unformattedMessage,
|
|
object arg0,
|
|
object arg1,
|
|
object arg2,
|
|
object arg3
|
|
)
|
|
{
|
|
// PERF NOTE: check the condition here instead of pushing it into
|
|
// the ThrowInternalError() method, because that method always
|
|
// allocates memory for its variable array of arguments
|
|
if (!condition)
|
|
{
|
|
ThrowInternalError(unformattedMessage, arg0, arg1, arg2, arg3);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region VerifyThrowInvalidOperation
|
|
|
|
/// <summary>
|
|
/// Throws an InvalidOperationException with the specified resource string
|
|
/// </summary>
|
|
/// <param name="resourceName">Resource to use in the exception</param>
|
|
/// <param name="args">Formatting args.</param>
|
|
internal static void ThrowInvalidOperation(string resourceName, params object[] args)
|
|
{
|
|
#if DEBUG
|
|
ResourceUtilities.VerifyResourceStringExists(resourceName);
|
|
#endif
|
|
if (s_throwExceptions)
|
|
{
|
|
throw new InvalidOperationException(ResourceUtilities.FormatResourceStringStripCodeAndKeyword(resourceName, args));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws an InvalidOperationException if the given condition is false.
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <param name="resourceName"></param>
|
|
internal static void VerifyThrowInvalidOperation
|
|
(
|
|
bool condition,
|
|
string resourceName
|
|
)
|
|
{
|
|
if (!condition)
|
|
{
|
|
// PERF NOTE: explicitly passing null for the arguments array
|
|
// prevents memory allocation
|
|
ThrowInvalidOperation(resourceName, null);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for one string format argument.
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <param name="resourceName"></param>
|
|
/// <param name="arg0"></param>
|
|
internal static void VerifyThrowInvalidOperation
|
|
(
|
|
bool condition,
|
|
string resourceName,
|
|
object arg0
|
|
)
|
|
{
|
|
// PERF NOTE: check the condition here instead of pushing it into
|
|
// the ThrowInvalidOperation() method, because that method always
|
|
// allocates memory for its variable array of arguments
|
|
if (!condition)
|
|
{
|
|
ThrowInvalidOperation(resourceName, arg0);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for two string format arguments.
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <param name="resourceName"></param>
|
|
/// <param name="arg0"></param>
|
|
/// <param name="arg1"></param>
|
|
internal static void VerifyThrowInvalidOperation
|
|
(
|
|
bool condition,
|
|
string resourceName,
|
|
object arg0,
|
|
object arg1
|
|
)
|
|
{
|
|
// PERF NOTE: check the condition here instead of pushing it into
|
|
// the ThrowInvalidOperation() method, because that method always
|
|
// allocates memory for its variable array of arguments
|
|
if (!condition)
|
|
{
|
|
ThrowInvalidOperation(resourceName, arg0, arg1);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for three string format arguments.
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <param name="resourceName"></param>
|
|
/// <param name="arg0"></param>
|
|
/// <param name="arg1"></param>
|
|
/// <param name="arg2"></param>
|
|
internal static void VerifyThrowInvalidOperation
|
|
(
|
|
bool condition,
|
|
string resourceName,
|
|
object arg0,
|
|
object arg1,
|
|
object arg2
|
|
)
|
|
{
|
|
// PERF NOTE: check the condition here instead of pushing it into
|
|
// the ThrowInvalidOperation() method, because that method always
|
|
// allocates memory for its variable array of arguments
|
|
if (!condition)
|
|
{
|
|
ThrowInvalidOperation(resourceName, arg0, arg1, arg2);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for four string format arguments.
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <param name="resourceName"></param>
|
|
/// <param name="arg0"></param>
|
|
/// <param name="arg1"></param>
|
|
/// <param name="arg2"></param>
|
|
/// <param name="arg3"></param>
|
|
internal static void VerifyThrowInvalidOperation
|
|
(
|
|
bool condition,
|
|
string resourceName,
|
|
object arg0,
|
|
object arg1,
|
|
object arg2,
|
|
object arg3
|
|
)
|
|
{
|
|
// PERF NOTE: check the condition here instead of pushing it into
|
|
// the ThrowInvalidOperation() method, because that method always
|
|
// allocates memory for its variable array of arguments
|
|
if (!condition)
|
|
{
|
|
ThrowInvalidOperation(resourceName, arg0, arg1, arg2, arg3);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region VerifyThrowArgument
|
|
|
|
/// <summary>
|
|
/// Throws an ArgumentException that can include an inner exception.
|
|
///
|
|
/// 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>
|
|
internal static void ThrowArgument
|
|
(
|
|
string resourceName,
|
|
params object[] args
|
|
)
|
|
{
|
|
ThrowArgument(null, resourceName, args);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws an ArgumentException that can include an inner exception.
|
|
///
|
|
/// 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>
|
|
/// <remarks>
|
|
/// This method is thread-safe.
|
|
/// </remarks>
|
|
/// <param name="innerException">Can be null.</param>
|
|
/// <param name="resourceName"></param>
|
|
/// <param name="args"></param>
|
|
private static void ThrowArgument
|
|
(
|
|
Exception innerException,
|
|
string resourceName,
|
|
params object[] args
|
|
)
|
|
{
|
|
#if DEBUG
|
|
ResourceUtilities.VerifyResourceStringExists(resourceName);
|
|
#endif
|
|
if (s_throwExceptions)
|
|
{
|
|
throw new ArgumentException(ResourceUtilities.FormatResourceStringStripCodeAndKeyword(resourceName, args), innerException);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws an ArgumentException if the given condition is false.
|
|
/// </summary>
|
|
/// <remarks>This method is thread-safe.</remarks>
|
|
/// <param name="condition"></param>
|
|
/// <param name="resourceName"></param>
|
|
internal static void VerifyThrowArgument
|
|
(
|
|
bool condition,
|
|
string resourceName
|
|
)
|
|
{
|
|
VerifyThrowArgument(condition, null, resourceName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for one string format argument.
|
|
/// </summary>
|
|
/// <remarks>This method is thread-safe.</remarks>
|
|
/// <param name="condition"></param>
|
|
/// <param name="resourceName"></param>
|
|
/// <param name="arg0"></param>
|
|
internal static void VerifyThrowArgument
|
|
(
|
|
bool condition,
|
|
string resourceName,
|
|
object arg0
|
|
)
|
|
{
|
|
VerifyThrowArgument(condition, null, resourceName, arg0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for two string format arguments.
|
|
/// </summary>
|
|
/// <remarks>This method is thread-safe.</remarks>
|
|
/// <param name="condition"></param>
|
|
/// <param name="resourceName"></param>
|
|
/// <param name="arg0"></param>
|
|
/// <param name="arg1"></param>
|
|
internal static void VerifyThrowArgument
|
|
(
|
|
bool condition,
|
|
string resourceName,
|
|
object arg0,
|
|
object arg1
|
|
)
|
|
{
|
|
VerifyThrowArgument(condition, null, resourceName, arg0, arg1);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for three string format arguments.
|
|
/// </summary>
|
|
/// <remarks>This method is thread-safe.</remarks>
|
|
internal static void VerifyThrowArgument
|
|
(
|
|
bool condition,
|
|
string resourceName,
|
|
object arg0,
|
|
object arg1,
|
|
object arg2
|
|
)
|
|
{
|
|
VerifyThrowArgument(condition, null, resourceName, arg0, arg1, arg2);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for four string format arguments.
|
|
/// </summary>
|
|
/// <remarks>This method is thread-safe.</remarks>
|
|
internal static void VerifyThrowArgument
|
|
(
|
|
bool condition,
|
|
string resourceName,
|
|
object arg0,
|
|
object arg1,
|
|
object arg2,
|
|
object arg3
|
|
)
|
|
{
|
|
VerifyThrowArgument(condition, null, resourceName, arg0, arg1, arg2, arg3);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws an ArgumentException that includes an inner exception, if
|
|
/// the given condition is false.
|
|
/// </summary>
|
|
/// <remarks>This method is thread-safe.</remarks>
|
|
/// <param name="condition"></param>
|
|
/// <param name="innerException">Can be null.</param>
|
|
/// <param name="resourceName"></param>
|
|
internal static void VerifyThrowArgument
|
|
(
|
|
bool condition,
|
|
Exception innerException,
|
|
string resourceName
|
|
)
|
|
{
|
|
if (!condition)
|
|
{
|
|
// PERF NOTE: explicitly passing null for the arguments array
|
|
// prevents memory allocation
|
|
ThrowArgument(innerException, resourceName, null);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for one string format argument.
|
|
/// </summary>
|
|
/// <remarks>This method is thread-safe.</remarks>
|
|
/// <param name="condition"></param>
|
|
/// <param name="innerException"></param>
|
|
/// <param name="resourceName"></param>
|
|
/// <param name="arg0"></param>
|
|
internal static void VerifyThrowArgument
|
|
(
|
|
bool condition,
|
|
Exception innerException,
|
|
string resourceName,
|
|
object arg0
|
|
)
|
|
{
|
|
// PERF NOTE: check the condition here instead of pushing it into
|
|
// the ThrowArgument() method, because that method always allocates
|
|
// memory for its variable array of arguments
|
|
if (!condition)
|
|
{
|
|
ThrowArgument(innerException, resourceName, arg0);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for two string format arguments.
|
|
/// </summary>
|
|
/// <remarks>This method is thread-safe.</remarks>
|
|
/// <param name="condition"></param>
|
|
/// <param name="innerException"></param>
|
|
/// <param name="resourceName"></param>
|
|
/// <param name="arg0"></param>
|
|
/// <param name="arg1"></param>
|
|
internal static void VerifyThrowArgument
|
|
(
|
|
bool condition,
|
|
Exception innerException,
|
|
string resourceName,
|
|
object arg0,
|
|
object arg1
|
|
)
|
|
{
|
|
// PERF NOTE: check the condition here instead of pushing it into
|
|
// the ThrowArgument() method, because that method always allocates
|
|
// memory for its variable array of arguments
|
|
if (!condition)
|
|
{
|
|
ThrowArgument(innerException, resourceName, arg0, arg1);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for three string format arguments.
|
|
/// </summary>
|
|
/// <remarks>This method is thread-safe.</remarks>
|
|
internal static void VerifyThrowArgument
|
|
(
|
|
bool condition,
|
|
Exception innerException,
|
|
string resourceName,
|
|
object arg0,
|
|
object arg1,
|
|
object arg2
|
|
)
|
|
{
|
|
// PERF NOTE: check the condition here instead of pushing it into
|
|
// the ThrowArgument() method, because that method always allocates
|
|
// memory for its variable array of arguments
|
|
if (!condition)
|
|
{
|
|
ThrowArgument(innerException, resourceName, arg0, arg1, arg2);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overload for four string format arguments.
|
|
/// </summary>
|
|
/// <remarks>This method is thread-safe.</remarks>
|
|
internal static void VerifyThrowArgument
|
|
(
|
|
bool condition,
|
|
Exception innerException,
|
|
string resourceName,
|
|
object arg0,
|
|
object arg1,
|
|
object arg2,
|
|
object arg3
|
|
)
|
|
{
|
|
// PERF NOTE: check the condition here instead of pushing it into
|
|
// the ThrowArgument() method, because that method always allocates
|
|
// memory for its variable array of arguments
|
|
if (!condition)
|
|
{
|
|
ThrowArgument(innerException, resourceName, arg0, arg1, arg2, arg3);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region VerifyThrowArgumentXXX
|
|
|
|
/// <summary>
|
|
/// Throws an argument out of range exception.
|
|
/// </summary>
|
|
internal static void ThrowArgumentOutOfRange(string parameterName)
|
|
{
|
|
if (s_throwExceptions)
|
|
{
|
|
throw new ArgumentOutOfRangeException(parameterName);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws an ArgumentOutOfRangeException using the given parameter name
|
|
/// if the condition is false.
|
|
/// </summary>
|
|
internal static void VerifyThrowArgumentOutOfRange(bool condition, string parameterName)
|
|
{
|
|
if (!condition)
|
|
{
|
|
ThrowArgumentOutOfRange(parameterName);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws an ArgumentNullException if the given string parameter is null
|
|
/// and ArgumentException if it has zero length.
|
|
/// </summary>
|
|
/// <param name="parameter"></param>
|
|
/// <param name="parameterName"></param>
|
|
internal static void VerifyThrowArgumentLength(string parameter, string parameterName)
|
|
{
|
|
VerifyThrowArgumentNull(parameter, parameterName);
|
|
|
|
if (parameter.Length == 0 && s_throwExceptions)
|
|
{
|
|
throw new ArgumentException(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("Shared.ParameterCannotHaveZeroLength", parameterName));
|
|
}
|
|
}
|
|
|
|
#if !CLR2COMPATIBILITY
|
|
/// <summary>
|
|
/// Throws an ArgumentNullException if the given collection is null
|
|
/// and ArgumentException if it has zero length.
|
|
/// </summary>
|
|
/// <param name="parameter"></param>
|
|
/// <param name="parameterName"></param>
|
|
internal static void VerifyThrowArgumentLength<T>(IReadOnlyCollection<T> parameter, string parameterName)
|
|
{
|
|
VerifyThrowArgumentNull(parameter, parameterName);
|
|
|
|
if (parameter.Count == 0 && s_throwExceptions)
|
|
{
|
|
throw new ArgumentException(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("Shared.ParameterCannotHaveZeroLength", parameterName));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws an ArgumentException if the given collection is not null but of zero length.
|
|
/// </summary>
|
|
/// <param name="parameter"></param>
|
|
/// <param name="parameterName"></param>
|
|
internal static void VerifyThrowArgumentLengthIfNotNull<T>(IReadOnlyCollection<T> parameter, string parameterName)
|
|
{
|
|
if (parameter?.Count == 0 && s_throwExceptions)
|
|
{
|
|
throw new ArgumentException(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("Shared.ParameterCannotHaveZeroLength", parameterName));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Throws an ArgumentNullException if the given string parameter is null
|
|
/// and ArgumentException if it has zero length.
|
|
/// </summary>
|
|
/// <param name="parameter"></param>
|
|
/// <param name="parameterName"></param>
|
|
internal static void VerifyThrowArgumentInvalidPath(string parameter, string parameterName)
|
|
{
|
|
VerifyThrowArgumentNull(parameter, parameterName);
|
|
|
|
if (FileUtilities.PathIsInvalid(parameter) && s_throwExceptions)
|
|
{
|
|
throw new ArgumentException(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("Shared.ParameterCannotHaveInvalidPathChars", parameterName, parameter));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws an ArgumentException if the string has zero length, unless it is
|
|
/// null, in which case no exception is thrown.
|
|
/// </summary>
|
|
internal static void VerifyThrowArgumentLengthIfNotNull(string parameter, string parameterName)
|
|
{
|
|
if (parameter?.Length == 0 && s_throwExceptions)
|
|
{
|
|
throw new ArgumentException(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("Shared.ParameterCannotHaveZeroLength", parameterName));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws an ArgumentNullException if the given parameter is null.
|
|
/// </summary>
|
|
/// <remarks>This method is thread-safe.</remarks>
|
|
/// <param name="parameter"></param>
|
|
/// <param name="parameterName"></param>
|
|
internal static void VerifyThrowArgumentNull(object parameter, string parameterName)
|
|
{
|
|
VerifyThrowArgumentNull(parameter, parameterName, "Shared.ParameterCannotBeNull");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws an ArgumentNullException if the given parameter is null.
|
|
/// </summary>
|
|
/// <remarks>This method is thread-safe.</remarks>
|
|
internal static void VerifyThrowArgumentNull(object parameter, string parameterName, string resourceName)
|
|
{
|
|
if (parameter == null && s_throwExceptions)
|
|
{
|
|
// Most ArgumentNullException overloads append its own rather clunky multi-line message.
|
|
// So use the one overload that doesn't.
|
|
throw new ArgumentNullException(
|
|
ResourceUtilities.FormatResourceStringStripCodeAndKeyword(resourceName, parameterName),
|
|
(Exception)null);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies the given arrays are not null and have the same length
|
|
/// </summary>
|
|
/// <param name="parameter1"></param>
|
|
/// <param name="parameter2"></param>
|
|
/// <param name="parameter1Name"></param>
|
|
/// <param name="parameter2Name"></param>
|
|
internal static void VerifyThrowArgumentArraysSameLength(Array parameter1, Array parameter2, string parameter1Name, string parameter2Name)
|
|
{
|
|
VerifyThrowArgumentNull(parameter1, parameter1Name);
|
|
VerifyThrowArgumentNull(parameter2, parameter2Name);
|
|
|
|
if (parameter1.Length != parameter2.Length && s_throwExceptions)
|
|
{
|
|
throw new ArgumentException(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("Shared.ParametersMustHaveTheSameLength", parameter1Name, parameter2Name));
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region VerifyThrowObjectDisposed
|
|
|
|
internal static void VerifyThrowObjectDisposed(bool condition, string objectName)
|
|
{
|
|
{
|
|
if (s_throwExceptions && !condition)
|
|
{
|
|
throw new ObjectDisposedException(objectName);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
#endif
|
|
}
|
|
}
|