Make MSB4186 report resolved argument types and available overloads - #14281
Make MSB4186 report resolved argument types and available overloads#14281ViktorHofer with Copilot wants to merge 6 commits into
Conversation
Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR improves diagnosability of MSB4186 when a static property function call fails to bind to any overload by reporting (a) the resolved argument types and (b) the available overload parameter-type signatures, plus adds unit coverage and a new localized string resource.
Changes:
- Add
GenerateNoMatchingOverloadMessageinExpander.Function.LateBindExecuteto enrich the “no matching overload”MissingMethodExceptionmessage. - Introduce new localized resource
InvalidFunctionNoMatchingOverloadinStrings.resxand several.xlffiles. - Add unit test coverage validating that argument/overload types appear in the resulting MSB4186 message.
Show a summary per file
| File | Description |
|---|---|
| src/Build/Evaluation/Expander.Function.cs | Generates a detailed “no matching overload” message listing resolved argument types and available overload signatures. |
| src/Build/Resources/Strings.resx | Adds the new localizable string InvalidFunctionNoMatchingOverload used to enrich MSB4186. |
| src/Build.UnitTests/Evaluation/Expander_Tests.cs | Adds a regression test validating the enriched MSB4186 output contains expected type information. |
| src/Build/Resources/xlf/Strings.cs.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
| src/Build/Resources/xlf/Strings.de.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
| src/Build/Resources/xlf/Strings.es.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
| src/Build/Resources/xlf/Strings.fr.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
| src/Build/Resources/xlf/Strings.it.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
| src/Build/Resources/xlf/Strings.ja.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
| src/Build/Resources/xlf/Strings.ko.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
| src/Build/Resources/xlf/Strings.pl.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
| src/Build/Resources/xlf/Strings.pt-BR.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
| src/Build/Resources/xlf/Strings.ru.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
| src/Build/Resources/xlf/Strings.tr.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
| src/Build/Resources/xlf/Strings.zh-Hans.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
| src/Build/Resources/xlf/Strings.zh-Hant.xlf | Adds InvalidFunctionNoMatchingOverload trans-unit (new). |
Copilot's findings
- Files reviewed: 16/16 changed files
- Comments generated: 2
…for MSB4186 Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
|
/review |
|
✅ Expert Code Review (command) completed successfully! Caution agentic threat detected Backwards compatibility review complete. One MODERATE issue found: output format change on MSB4186's message body, plus missing ChangeWave gate required by evaluation engine policy. |
|
Caution agentic threat detected Code Simplification — ISSUESEVERITY: NIT FINDING: The List<string> overloads = new();
foreach (MethodInfo method in _receiverType.GetMethods(_bindingFlags)
.Where(m => String.Equals(m.Name, _methodMethodName, StringComparison.OrdinalIgnoreCase)))
{
overloads.Add($"{_methodMethodName}({String.Join(", ", method.GetParameters().Select(static p => p.ParameterType.FullName))})");
}RECOMMENDATION: Collapse to a single LINQ chain — this is an error path so LINQ overhead is acceptable, and the result is more direct: List<string> overloads = _receiverType.GetMethods(_bindingFlags)
.Where(m => String.Equals(m.Name, _methodMethodName, StringComparison.OrdinalIgnoreCase))
.Select(m => $"{_methodMethodName}({String.Join(", ", m.GetParameters().Select(static p => p.ParameterType.FullName))})")
.ToList();Everything else — the ternary for
|
There was a problem hiding this comment.
Caution
agentic threat detected
Threat detection flagged this output in warn mode. Manual review is REQUIRED before any follow-up automation.
Idiomatic C# Patterns — ISSUE
SEVERITY: MODERATE
FILE: src/Build/Evaluation/Expander.Function.cs
SCENARIO: Null checks in the new GenerateNoMatchingOverloadMessage method and its call site.
FINDING: Two null checks use the old == null / != null operators instead of the pattern-matching style that Rule 3 mandates and the CHECK list explicitly flags:
if (detailedMessage != null)at the call siteargs == nullin the ternary inside the method
RECOMMENDATION:
// call site
if (detailedMessage is not null)
// ternary guard
string providedTypes = args is null
? string.Empty
: string.Join(...);SEVERITY: NIT
FILE: src/Build/Evaluation/Expander.Function.cs
SCENARIO: String. (BCL type alias, uppercase) used throughout new code while immediately surrounding, unchanged code uses the lowercase string. keyword alias.
FINDING: New code uses String.Empty, String.Join (×3), and String.Equals, inconsistent with the adjacent string.Equals and the codebase-wide convention shown in Expander.cs.
RECOMMENDATION: Replace all four String. references with string.:
string.Empty
string.Join(", ", ...)
string.Equals(m.Name, _methodMethodName, StringComparison.OrdinalIgnoreCase)Generated by Expert Code Review (command) for #14281 · 1.6K AIC · ⊞ 30.1K
Comment /review to run again
|
@copilot resolve the feedback from the Expert reviewer |
… (MSB4186) Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
Addressed the Expert reviewer feedback in fa3b994: the two null checks in I left the |
|
@copilot resolve the build failures (you will see them when you build the repo) |
Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
Fixed in 9ce43e1. The build failed with IL2080 (trimming) because |
|
What does this error message look like in the console reporter vs terminal logger? Especially interested in potentially having a multiline layout for the overloads because of visual noise |
|
@baronfel — the enriched text is currently a single line (overloads comma-separated), embedded in the Console / ParallelConsole logger ( Terminal Logger ( Note one asymmetry: TL only enters the wrapping/indenting branch when the message already contains So there's a real tension: a multiline layout looks great in TL but is noisier in the console logger, and because the overloads sit mid-sentence inside |
|
Oof. It would be great if there was a way for us to not have to pick-and-choose which presentation(s) get preferential treatment. Structured messages might be great here. |
When a static property function's arguments can't be matched to any overload, MSB4186 surfaced only the generic framework "method not found" message at the top level. When the mismatch came from a nested property function returning an unexpected type (e.g. due to a changed global build input), root-causing required expert debugging.
Context
The failing binder path in
Expander.Function.LateBindExecuterethrew the originalMissingMethodException, whose message says nothing about the types that were actually resolved or which overloads exist.Changes Made
Expander.Function.cs— In the "no matching overload" branch ofLateBindExecute, build an enriched message (GenerateNoMatchingOverloadMessage) listing the resolved argument types and the parameter types of every available overload; falls back to the original exception when no overloads can be described.Strings.resx(+.xlf) — New localizableInvalidFunctionNoMatchingOverloadresource, embedded into the{1}slot of MSB4186.Expander_Tests.cs— Added coverage asserting the reported argument and overload types.Example —
$([MSBuild]::Add($([System.DateTime]::Now), 1))(a typedDateTimecan't coerce toAdd(double,double)/Add(long,long)) now yields:Testing
PropertyFunctionNoMatchingOverloadReportsTypesverifies both the resolved argument types and the overload parameter types appear in the error.Notes