Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 22, 2025

Summary

This PR adds fast-paths for two frequently-used ToolLocationHelper property functions to improve performance and debugging experience when building template projects.

Problem

When building a template classlib in .NET 10.0.100-preview.5 with property function reflection logging enabled, two ToolLocationHelper methods were being logged as requiring expensive reflection:

ReceiverType=Microsoft.Build.Utilities.ToolLocationHelper; ObjectInstanceType=; MethodName=GetPlatformSDKLocation(String, String)
ReceiverType=Microsoft.Build.Utilities.ToolLocationHelper; ObjectInstanceType=; MethodName=GetPlatformSDKDisplayName(String, String)

These methods were falling back to Type.InvokeMember with the default binder, which:

  • Performs expensive method binding
  • Throws first-chance MissingMethodException during the binding process
  • Negatively impacts debugging experience
  • Adds unnecessary performance overhead

Solution

Added fast-paths in WellKnownFunctions.cs for both methods following the established pattern used for other types like Math, Path, and Version:

else if (receiverType.FullName == "Microsoft.Build.Utilities.ToolLocationHelper")
{
    if (string.Equals(methodName, "GetPlatformSDKLocation", StringComparison.OrdinalIgnoreCase))
    {
        if (ParseArgs.TryGetArgs(args, out string? arg0, out string? arg1))
        {
            var method = receiverType.GetMethod("GetPlatformSDKLocation", new[] { typeof(string), typeof(string) });
            if (method != null)
            {
                returnVal = method.Invoke(null, new object?[] { arg0, arg1 });
                return true;
            }
        }
    }
    // Similar implementation for GetPlatformSDKDisplayName
}

The implementation:

  1. Identifies ToolLocationHelper by checking receiverType.FullName (since Build assembly doesn't reference Utilities assembly)
  2. Uses targeted GetMethod() with explicit parameter types to locate the method directly
  3. Invokes the method using method.Invoke() instead of expensive InvokeMember binding
  4. Avoids throwing and catching MissingMethodException

Testing

Added 3 comprehensive unit tests in Expander_Tests.cs:

  • PropertyFunctionToolLocationHelperGetPlatformSDKLocation - Validates GetPlatformSDKLocation fast-path
  • PropertyFunctionToolLocationHelperGetPlatformSDKDisplayName - Validates GetPlatformSDKDisplayName fast-path
  • PropertyFunctionToolLocationHelperBothMethodsTogether - Ensures both methods work together correctly

All tests pass successfully and verify that the property functions execute without throwing exceptions.

Benefits

  • Performance: Eliminates expensive binding process for these commonly-used methods
  • Debugging: Removes first-chance exceptions that clutter the debugger output
  • Logging: When LogPropertyFunctionsRequiringReflection is enabled, these methods will no longer be logged
  • Minimal changes: Only 29 lines added to WellKnownFunctions.cs, following surgical change principles

Fixes #10762

Original prompt

This section details on the original issue you should resolve

<issue_title>Add fast-paths for property functions used in template projects</issue_title>
<issue_description>When building a template classlib in .NET 10.0.100-preview.5, there are two property functions that don't have a fast path, according to the output from enabling the tracing

LogFunctionCall(receiverType, methodName, "PropertyFunctionsRequiringReflection", objectInstance, args);

The log is:

ReceiverType=Microsoft.Build.Utilities.ToolLocationHelper; ObjectInstanceType=; MethodName=GetPlatformSDKLocation(String, String)
ReceiverType=Microsoft.Build.Utilities.ToolLocationHelper; ObjectInstanceType=; MethodName=GetPlatformSDKDisplayName(String, String)

Each of these should get a fast path in src/Build/Evaluation/Expander/WellKnownFunctions.cs, following the conventions established in that file.</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #12024


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@dotnet-policy-service
Copy link
Contributor

Hello @@copilot, I noticed that you’re changing an .swr file or any file under src/Package/MSBuild.VSSetup.. Please make sure to validate this change by an experimental VS insertion. This is accomplished by pushing to an exp/* branch, which requires write permissions to this repo.

Copilot AI changed the title [WIP] Add fast-paths for property functions in template projects Add fast-paths for ToolLocationHelper property functions Oct 22, 2025
Copilot AI requested a review from JanProvaznik October 22, 2025 10:24
Copilot finished work on behalf of JanProvaznik October 22, 2025 10:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add fast-paths for property functions used in template projects

2 participants