Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET Framework MSBuild doesn't cast char to string in property functions #9976

Open
rainersigwald opened this issue Apr 5, 2024 · 4 comments
Labels
Area: Language Issues impacting the MSBuild programming language. backlog bug Priority:2 Work that is important, but not critical for the release triaged

Comments

@rainersigwald
Copy link
Member

Consider

<Project>
  <Target Name="Go">
    <Warning Text="$(P.EndsWith($([System.IO.Path]::DirectorySeparatorChar)))" />
  </Target>
</Project>

This works with .NET 8 MSBuild:

dotnet msbuild .\test.proj -p:P=\Some\Path\
MSBuild version 17.10.0-preview-24162-02+0326fd7c9 for .NET
  test succeeded with warnings (0.0s)
    S:\repro\dotnet\razor\pull\10220\test.proj(3,5): warning : True [S:\repro\dotnet\razor\pull\10220\test.proj]

Build succeeded with warnings in 0.0sdotnet msbuild .\test.proj -p:P=\Some\Path
MSBuild version 17.10.0-preview-24162-02+0326fd7c9 for .NET
  test succeeded with warnings (0.0s)
    S:\repro\dotnet\razor\pull\10220\test.proj(3,5): warning : False [S:\repro\dotnet\razor\pull\10220\test.proj]

Build succeeded with warnings in 0.0s

But MSBuild.exe doesn't like it:

msbuild .\test.proj -p:P=\Some\Path\
  test failed with 1 error(s) (0.0s)
    S:\repro\dotnet\razor\pull\10220\test.proj(3,14): error MSB4186: Invalid static method invocation syntax: "P.EndsWith($([System.IO.Path]::DirectorySeparatorChar))". Object of type 'System.Char' cannot be converted to type 'System.String'. Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(`a`, `b`)). Check that all parameters are defined, are of the correct type, and are specified in the right order.

Build failed with 1 error(s) in 0.0s

(seen while investigating dotnet/razor#10220)

Workaround

You can wrap the char-generating method:

diff --git a/test.proj b/test.proj
index 87fa27a..d08cd98 100644
--- a/test.proj
+++ b/test.proj
@@ -1,5 +1,5 @@
 <Project>
   <Target Name="Go">
-    <Warning Text="$(P.EndsWith($([System.IO.Path]::DirectorySeparatorChar)))" />
+    <Warning Text="$(P.EndsWith($([System.String]::new($([System.IO.Path]::DirectorySeparatorChar)))))" />
   </Target>
 </Project>
@rainersigwald rainersigwald added bug Area: Language Issues impacting the MSBuild programming language. labels Apr 5, 2024
@KalleOlaviNiemitalo
Copy link

The logic in LateBindExecute looks wonky: it first searches for a method that has the correct number of parameters and where all parameters are strings; then if it finds one, it calls that via MethodInfo.Invoke even if the arguments are not strings. If it did not find such a method, then it would use CoerceArguments, which can convert Char to String via Convert.ChangeType.

On .NET Core 2.0 and greater, String.EndsWith(Char) already exists; I guess Type.InvokeMember calls that and LateBindExecute is not entered.

@KalleOlaviNiemitalo
Copy link

This works too:

<Project>
  <Target Name="Go">
    <Warning Text="$(P.EndsWith($([System.IO.Path]::DirectorySeparatorChar), 'StringComparison.Ordinal'))" />
  </Target>
</Project>

because there is no String.EndsWith(String, String) method and thus LateBindExecute resorts to String.EndsWith(String, StringComparison) and goes to the CoerceArguments path.

@KalleOlaviNiemitalo
Copy link

Would it be possible to change the language so that quoting the argument as in $(P.EndsWith('$([System.IO.Path]::DirectorySeparatorChar)')) always coerces it to String?

@rainersigwald
Copy link
Member Author

Maybe? I certainly tried that while investigating this so I like the general idea. I haven't thought through the implications though.

@AR-May AR-May added backlog Priority:2 Work that is important, but not critical for the release triaged labels Apr 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Language Issues impacting the MSBuild programming language. backlog bug Priority:2 Work that is important, but not critical for the release triaged
Projects
None yet
Development

No branches or pull requests

3 participants