diff --git a/src/Build.UnitTests/Evaluation/Expander_Tests.cs b/src/Build.UnitTests/Evaluation/Expander_Tests.cs index b29a857dc69..a18e3702372 100644 --- a/src/Build.UnitTests/Evaluation/Expander_Tests.cs +++ b/src/Build.UnitTests/Evaluation/Expander_Tests.cs @@ -1292,6 +1292,55 @@ public void StaticMethodErrorMessageHaveMethodName1() Assert.True(false); } + + [Fact] + public void StaticMethodWithThrowawayParameterSupported() + { + MockLogger logger = Helpers.BuildProjectWithNewOMExpectSuccess(@" + + + Value is $([System.Int32]::TryParse(""3"", out _)) + + + + +"); + + logger.FullLog.ShouldContain("Value is True"); + } + + [Fact] + public void StaticMethodWithThrowawayParameterSupported2() + { + MockLogger logger = Helpers.BuildProjectWithNewOMExpectSuccess(@" + + + Value is $([System.Int32]::TryParse(""notANumber"", out _)) + + + + +"); + + logger.FullLog.ShouldContain("Value is False"); + } + + [Fact] + public void StaticMethodWithUnderscoreNotConfusedWithThrowaway() + { + MockLogger logger = Helpers.BuildProjectWithNewOMExpectSuccess(@" + + + Value is $([System.String]::Join('_', 'asdf', 'jkl')) + + + + +"); + + logger.FullLog.ShouldContain("Value is asdf_jkl"); + } + /// /// Creates a set of complicated item metadata and properties, and items to exercise /// the Expander class. The data here contains escaped characters, metadata that diff --git a/src/Build/Evaluation/Expander.cs b/src/Build/Evaluation/Expander.cs index 6d2b14dfdc6..c51531255b0 100644 --- a/src/Build/Evaluation/Expander.cs +++ b/src/Build/Evaluation/Expander.cs @@ -3597,8 +3597,17 @@ internal object Execute(object objectInstance, IPropertyProvider properties, // otherwise there is the potential of running a function twice! try { - // First use InvokeMember using the standard binder - this will match and coerce as needed - functionResult = _receiverType.InvokeMember(_methodMethodName, _bindingFlags, Type.DefaultBinder, objectInstance, args, CultureInfo.InvariantCulture); + // If there are any out parameters, try to figure out their type and create defaults for them as appropriate before calling the method. + if (args.Any(a => "out _".Equals(a))) + { + IEnumerable methods = _receiverType.GetMethods(_bindingFlags).Where(m => m.Name.Equals(_methodMethodName) && m.GetParameters().Length == args.Length); + functionResult = GetMethodResult(objectInstance, methods, args, 0); + } + else + { + // If there are no out parameters, use InvokeMember using the standard binder - this will match and coerce as needed + functionResult = _receiverType.InvokeMember(_methodMethodName, _bindingFlags, Type.DefaultBinder, objectInstance, args, CultureInfo.InvariantCulture); + } } // If we're invoking a method, then there are deeper attempts that can be made to invoke the method. // If not, we were asked to get a property or field but found that we cannot locate it. No further argument coercion is possible, so throw. @@ -3694,6 +3703,48 @@ private bool TryExecuteWellKnownFunctionWithPropertiesParam(IPropertyProvider return false; } + private object GetMethodResult(object objectInstance, IEnumerable methods, object[] args, int index) + { + for (int i = index; i < args.Length; i++) + { + if (args[i].Equals("out _")) + { + object toReturn = null; + foreach (MethodInfo method in methods) + { + Type t = method.GetParameters()[i].ParameterType; + args[i] = t.IsValueType ? Activator.CreateInstance(t) : null; + object currentReturnValue = GetMethodResult(objectInstance, methods, args, i + 1); + if (currentReturnValue is not null) + { + if (toReturn is null) + { + toReturn = currentReturnValue; + } + else if (!toReturn.Equals(currentReturnValue)) + { + // There were multiple methods that seemed viable and gave different results. We can't differentiate between them so throw. + ErrorUtilities.ThrowArgument("CouldNotDifferentiateBetweenCompatibleMethods", _methodMethodName, args.Length); + return null; + } + } + } + + return toReturn; + } + } + + try + { + return _receiverType.InvokeMember(_methodMethodName, _bindingFlags, Type.DefaultBinder, objectInstance, args, CultureInfo.InvariantCulture) ?? "null"; + } + catch (Exception) + { + // This isn't a viable option, but perhaps another set of parameters will work. + return null; + } + } + /// /// Shortcut to avoid calling into binding if we recognize some most common functions. /// Binding is expensive and throws first-chance MissingMethodExceptions, which is diff --git a/src/Build/Resources/Strings.resx b/src/Build/Resources/Strings.resx index 53df24ba2d9..00e17f913ab 100644 --- a/src/Build/Resources/Strings.resx +++ b/src/Build/Resources/Strings.resx @@ -604,6 +604,9 @@ LOCALIZATION: "{0}" is the expression that was bad. "{1}" is a message from an FX exception that describes why the expression is bad. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + MSB4184: The expression "{0}" cannot be evaluated. {1} {StrBegin="MSB4184: "} diff --git a/src/Build/Resources/xlf/Strings.cs.xlf b/src/Build/Resources/xlf/Strings.cs.xlf index c59ba7f91b5..f0c0bd15e9c 100644 --- a/src/Build/Resources/xlf/Strings.cs.xlf +++ b/src/Build/Resources/xlf/Strings.cs.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + Bylo nalezeno více přetížení pro metodu {0} s tímto počtem parametrů: {1}. To v současné době není podporováno. + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition diff --git a/src/Build/Resources/xlf/Strings.de.xlf b/src/Build/Resources/xlf/Strings.de.xlf index 1da92bd2dc3..690fc42a160 100644 --- a/src/Build/Resources/xlf/Strings.de.xlf +++ b/src/Build/Resources/xlf/Strings.de.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + Es wurden mehrere Überladungen für die Methode „{0}“ mit {1} Parametern gefunden. Dies wird derzeit nicht unterstützt. + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition diff --git a/src/Build/Resources/xlf/Strings.es.xlf b/src/Build/Resources/xlf/Strings.es.xlf index df05725c5e4..e4fbe790b63 100644 --- a/src/Build/Resources/xlf/Strings.es.xlf +++ b/src/Build/Resources/xlf/Strings.es.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + Encontradas múltiples sobrecargas para el método "{0}" con {1} parámetro(s). Esto no se admite actualmente. + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition diff --git a/src/Build/Resources/xlf/Strings.fr.xlf b/src/Build/Resources/xlf/Strings.fr.xlf index 4fb21225130..6ae82144221 100644 --- a/src/Build/Resources/xlf/Strings.fr.xlf +++ b/src/Build/Resources/xlf/Strings.fr.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + Plusieurs surcharges ont été trouvées pour la méthode « {0} » avec le(s) paramètre(s) {1}. Cela n’est actuellement pas pris en charge. + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition diff --git a/src/Build/Resources/xlf/Strings.it.xlf b/src/Build/Resources/xlf/Strings.it.xlf index b2d59875e50..a43403d97aa 100644 --- a/src/Build/Resources/xlf/Strings.it.xlf +++ b/src/Build/Resources/xlf/Strings.it.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition diff --git a/src/Build/Resources/xlf/Strings.ja.xlf b/src/Build/Resources/xlf/Strings.ja.xlf index b8d4ba74700..0395a5b04ef 100644 --- a/src/Build/Resources/xlf/Strings.ja.xlf +++ b/src/Build/Resources/xlf/Strings.ja.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + {1} パラメーターを持つメソッド "{0}" に対して複数のオーバーロードが見つかりました。これは現在サポートされていません。 + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition diff --git a/src/Build/Resources/xlf/Strings.ko.xlf b/src/Build/Resources/xlf/Strings.ko.xlf index 82287483bf4..314da0b4ac3 100644 --- a/src/Build/Resources/xlf/Strings.ko.xlf +++ b/src/Build/Resources/xlf/Strings.ko.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + {1} 매개 변수가 있는 "{0}" 메서드에 오버로드가 여러 개 발견되었습니다. 이는 현재 지원되지 않습니다. + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition diff --git a/src/Build/Resources/xlf/Strings.pl.xlf b/src/Build/Resources/xlf/Strings.pl.xlf index 63ace7582fc..ee967d20935 100644 --- a/src/Build/Resources/xlf/Strings.pl.xlf +++ b/src/Build/Resources/xlf/Strings.pl.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition diff --git a/src/Build/Resources/xlf/Strings.pt-BR.xlf b/src/Build/Resources/xlf/Strings.pt-BR.xlf index f857b1890f2..23e2c37ec4a 100644 --- a/src/Build/Resources/xlf/Strings.pt-BR.xlf +++ b/src/Build/Resources/xlf/Strings.pt-BR.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + Foram encontradas várias sobrecargas para o método "{0}" com parâmetros {1}. No momento, não há suporte para isso. + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition diff --git a/src/Build/Resources/xlf/Strings.ru.xlf b/src/Build/Resources/xlf/Strings.ru.xlf index b5107f73d35..77ffd158b99 100644 --- a/src/Build/Resources/xlf/Strings.ru.xlf +++ b/src/Build/Resources/xlf/Strings.ru.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + Обнаружено несколько перегрузок для метода "{0}" с параметрами {1}. Это сейчас не поддерживается. + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition diff --git a/src/Build/Resources/xlf/Strings.tr.xlf b/src/Build/Resources/xlf/Strings.tr.xlf index 21edf0d75d2..67886fd1383 100644 --- a/src/Build/Resources/xlf/Strings.tr.xlf +++ b/src/Build/Resources/xlf/Strings.tr.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + {1} parametreye sahip "{0}" yöntemi için birden çok aşırı yükleme bulundu. Bu şu anda desteklenmiyor. + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition diff --git a/src/Build/Resources/xlf/Strings.zh-Hans.xlf b/src/Build/Resources/xlf/Strings.zh-Hans.xlf index 350c89b3d35..bda8874997c 100644 --- a/src/Build/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/Build/Resources/xlf/Strings.zh-Hans.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition diff --git a/src/Build/Resources/xlf/Strings.zh-Hant.xlf b/src/Build/Resources/xlf/Strings.zh-Hant.xlf index 4d3f605a97d..c0dacb572be 100644 --- a/src/Build/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/Build/Resources/xlf/Strings.zh-Hant.xlf @@ -222,6 +222,11 @@ Failed to find the specified custom check assembly: '{0}'. Please check if it exists. The message is emitted when the custom check assembly can not be found. + + Found multiple overloads for method "{0}" with {1} parameter(s). That is currently not supported. + 在具有 {1} 參數的方法 "{0}" 發現多個多載。目前不支援此功能。 + + Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition Failed to load the custom check type: '{0}' from the assembly: '{1}'. Make sure it inherits the Microsoft.Build.Experimental.BuildCheck.Check base class. If it is not intended to be a custom check, than it should not be exposed. More info: https://github.com/dotnet/msbuild/blob/main/documentation/specs/proposed/BuildCheck-Architecture.md#acquisition