Shorten BindingSourceGen hint names - #35986
Conversation
Use a compact stable hash instead of embedding the full source file path in generated source hint names to avoid MAX_PATH issues on Windows. Fixes #35857 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35986Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35986" |
Parse-PhaseOutcomes determined the gate and fix signal labels by regex-parsing prose in gate/content.md and try-fix/content.md. This was fragile and mislabeled PR #35986: the winner was try-fix-1 (isPRFix=false → an alternative beat the PR), which should be s/agent-fix-win, but the prose parser produced "lose" and applied s/agent-fix-pr-picked. The gate was FAILED, but the old regex (^Result:) never matches the real "### Gate Result:" header, so no gate label was applied at all. Use the machine-readable artifacts the pipeline already writes: - Fix ← winner.json: isPRFix=false → 'win' (s/agent-fix-win), isPRFix=true → 'lose' (s/agent-fix-pr-picked); falls back to the winner name (try-fix-* vs pr/pr-plus-reviewer). Missing/invalid winner.json → no fix label (so review-incomplete runs don't get a guessed fix label). - Gate ← gate/gate-result.txt (PASSED|SKIPPED|FAILED). SKIPPED means "no runnable tests" → no gate label (previously wrongly mapped to failed). Falls back to the real "### Gate Result:" header when the file is absent. Adds Update-AgentLabels.Tests.ps1 (15 cases) covering win/lose/missing/malformed winner.json, passed/failed/skipped gate-result, the header fallback, and the exact #35986 scenario (try-fix winner + failed gate → fix-win + gate-failed). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 1 findings
See inline comments for details.
|
|
||
| var fileName = $"{location.FilePath}-GeneratedBindingInterceptors-{location.Line}-{location.Column}.g.cs"; | ||
| var sanitizedFileName = fileName.Replace('/', '-').Replace('\\', '-').Replace(':', '-'); | ||
| var hintName = CreateHintName(location); |
There was a problem hiding this comment.
[major] XAML & Bindings — This only stabilizes the AddSource hint name; the generated interceptor method name still uses SimpleLocation.GetHashCode() via uniqueId below. Because SimpleLocation contains FilePath, record hashing ultimately includes string.GetHashCode(), which is process-randomized on .NET, so identical inputs can emit different generated method names and generated source content across compiler/server processes. Use a stable ID such as InterceptableLocation.Data or the same stable location hash for the method suffix as well, and cover it with a determinism regression test.
There was a problem hiding this comment.
Addressed in e1b2dd6: the generated interceptor method suffix now uses the same stable location hash instead of SimpleLocation.GetHashCode(), and there is a regression test covering the stable method name.
Replace randomized location GetHashCode usage in generated interceptor method names with the stable location hash used by hint names. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
This comment has been minimized.
This comment has been minimized.
MauiBot
left a comment
There was a problem hiding this comment.
AI Review Summary
@jfversluis — new AI review results are available based on this last commit:
e1b2dd6. To request a fresh review after new comments or commits, comment/review rerun.
🗂️ Review Sessions — click to expand
🚦 Gate — Test Before & After Fix
Gate Result: ✅ PASSED
Platform: ANDROID · Base: main · Merge base: 0395a53b
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
🧪 IntegrationTests IntegrationTests |
✅ FAIL — 93s | ✅ PASS — 78s |
🔴 Without fix — 🧪 IntegrationTests: FAIL ✅ · 93s
(truncated to last 15,000 chars)
hException()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 51
at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 46
at BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBinding() in /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs:line 26
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Failed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithForcedConditionalAccessAfterCast [99 ms]
Error Message:
System.InvalidOperationException : Sequence contains no matching element
Stack Trace:
at System.Linq.ThrowHelper.ThrowNoMatchException()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 51
at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 46
at BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithForcedConditionalAccessAfterCast() in /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs:line 1265
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Passed BindingSourceGen.UnitTests.IntegrationTests.IgnoresOtherOtherCreateMethod [111 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.IgnoresOtherBindingCreateMethod [139 ms]
Failed BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBinding_WithInitSetter [106 ms]
Error Message:
System.InvalidOperationException : Sequence contains no matching element
Stack Trace:
at System.Linq.ThrowHelper.ThrowNoMatchException()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 51
at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 46
at BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBinding_WithInitSetter() in /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs:line 2027
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
[xUnit.net 00:00:05.48] BindingSourceGen.UnitTests.IntegrationTests.GeneratedMethodNameUsesStableLocationId [FAIL]
[xUnit.net 00:00:05.48] System.InvalidOperationException : Sequence contains no matching element
[xUnit.net 00:00:05.48] Stack Trace:
[xUnit.net 00:00:05.48] at System.Linq.ThrowHelper.ThrowNoMatchException()
[xUnit.net 00:00:05.48] at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
[xUnit.net 00:00:05.48] /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs(51,0): at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result)
[xUnit.net 00:00:05.48] /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs(46,0): at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result)
[xUnit.net 00:00:05.48] /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs(153,0): at BindingSourceGen.UnitTests.IntegrationTests.GeneratedMethodNameUsesStableLocationId()
[xUnit.net 00:00:05.48] at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
[xUnit.net 00:00:05.48] at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
[xUnit.net 00:00:05.62] BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBindingWhenNullableDisabledNonNullableValueType [FAIL]
[xUnit.net 00:00:05.62] System.InvalidOperationException : Sequence contains no matching element
[xUnit.net 00:00:05.62] Stack Trace:
[xUnit.net 00:00:05.62] at System.Linq.ThrowHelper.ThrowNoMatchException()
[xUnit.net 00:00:05.62] at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
[xUnit.net 00:00:05.62] /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs(51,0): at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result)
[xUnit.net 00:00:05.62] /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs(46,0): at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result)
[xUnit.net 00:00:05.62] /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs(347,0): at BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBindingWhenNullableDisabledNonNullableValueType()
[xUnit.net 00:00:05.62] at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
[xUnit.net 00:00:05.62] at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
[xUnit.net 00:00:05.80] BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithPrivateReadonlyProperty [FAIL]
[xUnit.net 00:00:05.80] System.InvalidOperationException : Sequence contains no matching element
[xUnit.net 00:00:05.80] Stack Trace:
[xUnit.net 00:00:05.80] at System.Linq.ThrowHelper.ThrowNoMatchException()
[xUnit.net 00:00:05.80] at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
[xUnit.net 00:00:05.80] /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs(51,0): at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result)
[xUnit.net 00:00:05.80] /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs(46,0): at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result)
[xUnit.net 00:00:05.80] /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs(1910,0): at BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithPrivateReadonlyProperty()
[xUnit.net 00:00:05.80] at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
[xUnit.net 00:00:05.80] at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
[xUnit.net 00:00:05.99] BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNullableObjectAndNullableReferenceTypeProperty_SetBinding [FAIL]
[xUnit.net 00:00:05.99] System.InvalidOperationException : Sequence contains no matching element
[xUnit.net 00:00:05.99] Stack Trace:
[xUnit.net 00:00:05.99] at System.Linq.ThrowHelper.ThrowNoMatchException()
[xUnit.net 00:00:05.99] at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
[xUnit.net 00:00:05.99] /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs(51,0): at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result)
[xUnit.net 00:00:05.99] /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs(46,0): at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result)
[xUnit.net 00:00:05.99] /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs(2437,0): at BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNullableObjectAndNullableReferenceTypeProperty_SetBinding()
[xUnit.net 00:00:05.99] at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
[xUnit.net 00:00:05.99] at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
[xUnit.net 00:00:06.13] BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNonNullableReferenceTypesCasts [FAIL]
[xUnit.net 00:00:06.13] System.InvalidOperationException : Sequence contains no matching element
[xUnit.net 00:00:06.13] Stack Trace:
[xUnit.net 00:00:06.13] at System.Linq.ThrowHelper.ThrowNoMatchException()
[xUnit.net 00:00:06.13] at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
[xUnit.net 00:00:06.13] /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs(51,0): at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result)
[xUnit.net 00:00:06.13] /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs(46,0): at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result)
[xUnit.net 00:00:06.13] /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs(1132,0): at BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNonNullableReferenceTypesCasts()
[xUnit.net 00:00:06.13] at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
[xUnit.net 00:00:06.13] at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
[xUnit.net 00:00:06.14] Finished: Controls.BindingSourceGen.UnitTests
Failed BindingSourceGen.UnitTests.IntegrationTests.GeneratedMethodNameUsesStableLocationId [162 ms]
Error Message:
System.InvalidOperationException : Sequence contains no matching element
Stack Trace:
at System.Linq.ThrowHelper.ThrowNoMatchException()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 51
at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 46
at BindingSourceGen.UnitTests.IntegrationTests.GeneratedMethodNameUsesStableLocationId() in /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs:line 153
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Failed BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBindingWhenNullableDisabledNonNullableValueType [141 ms]
Error Message:
System.InvalidOperationException : Sequence contains no matching element
Stack Trace:
at System.Linq.ThrowHelper.ThrowNoMatchException()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 51
at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 46
at BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBindingWhenNullableDisabledNonNullableValueType() in /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs:line 347
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Failed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithPrivateReadonlyProperty [171 ms]
Error Message:
System.InvalidOperationException : Sequence contains no matching element
Stack Trace:
at System.Linq.ThrowHelper.ThrowNoMatchException()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 51
at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 46
at BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithPrivateReadonlyProperty() in /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs:line 1910
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Failed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNullableObjectAndNullableReferenceTypeProperty_SetBinding [189 ms]
Error Message:
System.InvalidOperationException : Sequence contains no matching element
Stack Trace:
at System.Linq.ThrowHelper.ThrowNoMatchException()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 51
at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 46
at BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNullableObjectAndNullableReferenceTypeProperty_SetBinding() in /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs:line 2437
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Failed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNonNullableReferenceTypesCasts [144 ms]
Error Message:
System.InvalidOperationException : Sequence contains no matching element
Stack Trace:
at System.Linq.ThrowHelper.ThrowNoMatchException()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at SourceGenHelpers.GetGeneratedBindingFile(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 51
at SourceGenHelpers.GetGeneratedBindingSource(CodeGeneratorResult result) in /_/src/Controls/tests/BindingSourceGen.UnitTests/SourceGenHelpers.cs:line 46
at BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNonNullableReferenceTypesCasts() in /_/src/Controls/tests/BindingSourceGen.UnitTests/IntegrationTests.cs:line 1132
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Test Run Failed.
Total tests: 32
Passed: 3
Failed: 29
Total time: 6.7104 Seconds
🟢 With fix — 🧪 IntegrationTests: PASS ✅ · 78s
Determining projects to restore...
All projects are up-to-date for restore.
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14643801
Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14643801
Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14643801
Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14643801
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
Controls.BindingSourceGen.UnitTests -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen.UnitTests/Debug/net10.0/Controls.BindingSourceGen.UnitTests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen.UnitTests/Debug/net10.0/Controls.BindingSourceGen.UnitTests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.06] Discovering: Controls.BindingSourceGen.UnitTests
[xUnit.net 00:00:00.12] Discovered: Controls.BindingSourceGen.UnitTests
[xUnit.net 00:00:00.13] Starting: Controls.BindingSourceGen.UnitTests
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNullableReferenceTypesCasts(bindingLambda: "static (MySourceClass s) => ((Z?)((Y?)((X?)s.A)?.B"···) [1 s]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNullableReferenceTypesCasts(bindingLambda: "static (MySourceClass s) => (((s.A as X)?.B as Y)?"···) [108 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithPrivatePropertySetter [216 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingReferencingPrivateField [152 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingReferencingPrivateProperty [104 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBindingWhenNullableDisabledAndPropertyNullable(source: "// Reference Type\n#nullable disable\nusing Micros"···) [93 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBindingWhenNullableDisabledAndPropertyNullable(source: "// Conditional access operator\n#nullable disable\"···) [99 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBindingWhenNullableDisabledAndPropertyNullable(source: "// Nullable value type on path\n#nullable disable\"···) [94 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBindingWhenNullableDisabledAndPropertyNullable(source: "// Nullable value type\n#nullable disable\nusing M"···) [97 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithPublicPropertyAndNonPublicSetter(setterVisibility: "protected", shouldUseUnsafeAccessor: True) [114 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithPublicPropertyAndNonPublicSetter(setterVisibility: "private", shouldUseUnsafeAccessor: True) [105 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithPublicPropertyAndNonPublicSetter(setterVisibility: "private protected", shouldUseUnsafeAccessor: True) [318 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithPublicPropertyAndNonPublicSetter(setterVisibility: "protected internal", shouldUseUnsafeAccessor: False) [188 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithPublicPropertyAndNonPublicSetter(setterVisibility: "internal", shouldUseUnsafeAccessor: False) [120 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNullableObjectAndNullableReferenceTypeProperty_Create [128 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBindingCreate [101 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateSetBindingWithXamlGeneratedSource [162 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GeneratedHintNameDoesNotIncludeSourceFilePath [104 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBindingWhenNullableDisabledAndNonNullableValueTypeInPath [127 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateCreateBindingWithXamlGeneratedSource [109 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBindingWhenNullableDisabledNonNullableValueTypeWithIndexers [166 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithIndexers [142 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBinding [102 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithForcedConditionalAccessAfterCast [115 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.IgnoresOtherOtherCreateMethod [83 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.IgnoresOtherBindingCreateMethod [165 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBinding_WithInitSetter [102 ms]
[xUnit.net 00:00:05.83] Finished: Controls.BindingSourceGen.UnitTests
Passed BindingSourceGen.UnitTests.IntegrationTests.GeneratedMethodNameUsesStableLocationId [111 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateSimpleBindingWhenNullableDisabledNonNullableValueType [214 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithPrivateReadonlyProperty [195 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNullableObjectAndNullableReferenceTypeProperty_SetBinding [160 ms]
Passed BindingSourceGen.UnitTests.IntegrationTests.GenerateBindingWithNonNullableReferenceTypesCasts [118 ms]
Test Run Successful.
Total tests: 32
Passed: 32
Total time: 6.4030 Seconds
📁 Fix files reverted (1 files)
src/Controls/src/BindingSourceGen/BindingSourceGenerator.cs
📋 Pre-Flight — Context & Validation
Issue: #35857 - Binding generators easily exceeds MAX_PATH on Windows
PR: #35986 - Shorten BindingSourceGen hint names
Platforms Affected: Windows path-length bug in compile-time source generation; tested platform requested: android (unit test path is platform-neutral)
Files Changed: 1 implementation, 2 test
Key Findings
- The issue reports generated BindingSourceGen hint names embedding the original absolute source file path, producing paths longer than Windows
MAX_PATHwhenEmitCompilerGeneratedFilesmirrors hint names to disk. - The PR replaces sanitized full-path hint names with
BindingSourceGen-{stableHash}-{line}-{column}.g.csand uses the same stable hash in generated interceptor method names. - A prior MauiBot major finding noted that method names still used nondeterministic
SimpleLocation.GetHashCode(); the current PR head addresses it by usingstableLocationIdfor both hint names and method suffixes. - Changed tests are unit/source-generator tests; no UI test categories are directly impacted.
Code Review Summary
Verdict: NEEDS_DISCUSSION
Confidence: low
Errors: 0 | Warnings: 0 | Suggestions: 0
Key code review findings:
- No actionable code findings.
- Prior major review finding is fixed:
src/Controls/src/BindingSourceGen/BindingSourceGenerator.cs:50-60now uses a stable hash for both generated file hint and generated method suffix. - Failure modes checked: multiple files with same line/column remain distinct via file-path participation in hash; raw paths are no longer embedded in hint names; generated output is deterministic across compiler processes.
- CI status could not be independently classified because
ghis unauthenticated in this environment, so confidence is capped low by the code-review skill rules.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35986 | Stable FNV-style hash of `FilePath | Line | Column` used for both compact generated hint names and generated interceptor method suffixes | ✅ PASSED (Gate) |
🔬 Code Review — Deep Analysis
Code Review — PR #35986
Independent Assessment
What this changes: Replaces SimpleLocation.GetHashCode()/full-path-based generated names in BindingSourceGen with a stable 64-bit FNV-style hash of FilePath|Line|Column, used for both generated hint names and interceptor method suffixes.
Inferred motivation: Avoid long/absolute generated file paths and nondeterministic generated method names.
Reconciliation with PR Narrative
Author claims: Shorten BindingSourceGen hint names to avoid Windows MAX_PATH issues when compiler-generated files are emitted.
Agreement/disagreement: Agrees. The implementation also fixes prior method-name nondeterminism by using the stable ID at BindingSourceGenerator.cs:50-60.
Prior Review Reconciliation
| Prior ❌ Error Finding | Source | Status | Evidence |
|---|---|---|---|
Generated method suffix still used SimpleLocation.GetHashCode() / process-randomized string hashing |
MauiBot inline [major] |
✅ Fixed | Current code uses stableLocationId for hint name and method suffix at BindingSourceGenerator.cs:50-60; regression test at IntegrationTests.cs:140-153. |
Blast Radius Assessment
- Runs for all instances: No runtime impact; compile-time source generator only for supported typed binding calls.
- Startup impact: No.
- Static/shared state: No new mutable static state.
CI Status
- Required-check result: unavailable via
gh pr checks --requiredbecauseghis unauthenticated. - Classification: undetermined. Public check-run data for head SHA shows some failing/cancelled checks, but required-gate status/root cause could not be classified here.
- Action taken: confidence capped low; no GitHub comments posted.
Findings
No ❌ Error,
Failure-Mode Probing
- Multiple bindings on same line/column in different files: file path participates in the stable hash, so names remain distinct.
- Invalid/long source paths: raw path is no longer embedded in the hint name.
- Determinism across compiler processes: avoids
GetHashCode()and uses explicit unchecked hashing. - Common generated file collision: helper filters
BindingSourceGen-, while common file remainsGeneratedBindingInterceptorsCommon.g.cs.
Focused validation run:
dotnet test src/Controls/tests/BindingSourceGen.UnitTests/Controls.BindingSourceGen.UnitTests.csproj --no-restore --filter FullyQualifiedName~BindingSourceGen.UnitTests.IntegrationTests --verbosity minimal — 32/32 passed.
Verdict: NEEDS_DISCUSSION
Confidence: low
Summary: Code review found no actionable code issues, and the prior major finding is fixed. However, CI required-check status is unavailable/undetermined due unauthenticated gh and public check-run failures could not be classified, so this cannot be LGTM under the skill rules.
🛠️ Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | maui-expert-reviewer | Content/source-span generated identity; hashes source text checksum plus syntax span and uses the ID for hint and method names | ✅ PASS | 3 files | Passed focused BindingSourceGen IntegrationTests, but not better than PR due duplicate-file collision risk |
| 2 | maui-expert-reviewer | Project-relative path identity using MSBuildProjectDirectory, with external-file fallback |
❌ FAIL | 3 files | Did not compile within iteration window; netstandard2.0 and nullable-flow issues; more complex than PR |
| 3 | maui-expert-reviewer | Compilation-local deterministic ordinal IDs after collecting/sorting all binding candidates | ✅ PASS | 3 files | Passed focused BindingSourceGen IntegrationTests, but not better than PR due ordinal renumbering and broader incremental-generator churn |
| PR | PR #35986 | Stable FNV-style hash of `FilePath | Line | Column` used for compact hint names and method suffixes | ✅ PASSED (Gate) |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| gpt-5.5 / maui-expert-reviewer | 1 | Yes | Try content/span identity to avoid absolute paths entirely. |
| gpt-5.5 / maui-expert-reviewer | 2 | Yes | Try project-relative path identity to preserve per-file uniqueness without checkout-root sensitivity. |
| gpt-5.5 / maui-expert-reviewer | 3 | Yes | Try compilation-local deterministic ordinal IDs to avoid hashes/path-derived emitted IDs. |
| gpt-5.5 / maui-expert-reviewer | 4 | No | NO NEW IDEAS |
Exhausted: Yes
Selected Fix: PR #35986 — Candidate #1 and #3 passed focused tests, but neither is demonstrably better. Candidate #1 weakens uniqueness for duplicated files; Candidate #3 creates ordinal renumbering/incremental churn; Candidate #2 failed and adds analyzer-config complexity. The PR's current stable path/location hash remains the simplest robust fix.
Notes
- Gate verification was not rerun; caller supplied Gate ✅ PASSED.
EstablishBrokenBaseline.ps1could not run in the shared worktree because unrelated local changes made the worktree dirty. Candidate edits/tests were isolated in temporary worktrees, and each candidate directory records this inbaseline.log.
🏁 Report — Final Recommendation
Comparative Fix Report — PR #35986
Candidate ranking
| Rank | Candidate | Regression result | Assessment |
|---|---|---|---|
| 1 | pr |
PASS | Best overall. Uses a compact deterministic hash of `FilePath |
| 2 | pr-plus-reviewer |
PASS | Equivalent to pr. No actionable reviewer feedback was available to apply, so this candidate adds no improvement over the submitted PR. |
| 3 | try-fix-1 |
PASS | Content/checksum plus source-span identity avoids paths entirely, but can collide for duplicated source files with identical content and identical binding spans. That weakens uniqueness compared with the PR's path/location identity. |
| 4 | try-fix-3 |
PASS | Deterministic ordinal IDs avoid hashes and emitted path-derived IDs, but collecting and sorting all bindings is a broader incremental-generator change and adding/removing an earlier-sorted binding can renumber later generated files/methods, increasing churn. |
| 5 | try-fix-2 |
FAIL | Project-relative path identity is more complex, depends on analyzer config, and failed to compile within the iteration window. Per ranking rules, failed regression candidates are lower than passing candidates. |
Winner
pr is the winning candidate.
The raw PR fix is the simplest robust solution that satisfies the bug: generated hint names no longer contain long absolute source paths, generated method names no longer depend on GetHashCode(), and file path plus line/column keeps separate files distinct. The passing try-fix candidates explore useful alternatives, but each introduces a material downside not present in the PR; the failed candidate is not mergeable.
Notes
- Gate result supplied by the orchestrator: tests fail without the fix and pass with the fix.
pr-plus-reviewerremains a no-op candidate because no actionable expert-review changes were identified.- Since the winner is the PR fix, no external candidate diff is required in
winner.json.
🧭 Next Steps — review latest findings
No alternative fix was selected for this run. Review the session findings and CI results before merging.
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! Fixes #35857 Reviewer: @StephaneDelcroix ## Description The BindingSourceGen source generator used the full source file path as part of its generated source hint name. When `EmitCompilerGeneratedFiles` is enabled, Roslyn mirrors that hint name into the generated file path, which can exceed Windows `MAX_PATH` for projects in deeper directory structures. This changes the generated binding source hint name to use a compact stable hash of the source file path plus the binding line and column, avoiding long absolute paths while preserving deterministic uniqueness. ## Testing - `dotnet test src\Controls\tests\BindingSourceGen.UnitTests\Controls.BindingSourceGen.UnitTests.csproj --no-restore --verbosity minimal` --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! Fixes #35857 Reviewer: @StephaneDelcroix ## Description The BindingSourceGen source generator used the full source file path as part of its generated source hint name. When `EmitCompilerGeneratedFiles` is enabled, Roslyn mirrors that hint name into the generated file path, which can exceed Windows `MAX_PATH` for projects in deeper directory structures. This changes the generated binding source hint name to use a compact stable hash of the source file path plus the binding line and column, avoiding long absolute paths while preserving deterministic uniqueness. ## Testing - `dotnet test src\Controls\tests\BindingSourceGen.UnitTests\Controls.BindingSourceGen.UnitTests.csproj --no-restore --verbosity minimal` --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! Fixes #35857 Reviewer: @StephaneDelcroix ## Description The BindingSourceGen source generator used the full source file path as part of its generated source hint name. When `EmitCompilerGeneratedFiles` is enabled, Roslyn mirrors that hint name into the generated file path, which can exceed Windows `MAX_PATH` for projects in deeper directory structures. This changes the generated binding source hint name to use a compact stable hash of the source file path plus the binding line and column, avoiding long absolute paths while preserving deterministic uniqueness. ## Testing - `dotnet test src\Controls\tests\BindingSourceGen.UnitTests\Controls.BindingSourceGen.UnitTests.csproj --no-restore --verbosity minimal` --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! Fixes #35857 Reviewer: @StephaneDelcroix ## Description The BindingSourceGen source generator used the full source file path as part of its generated source hint name. When `EmitCompilerGeneratedFiles` is enabled, Roslyn mirrors that hint name into the generated file path, which can exceed Windows `MAX_PATH` for projects in deeper directory structures. This changes the generated binding source hint name to use a compact stable hash of the source file path plus the binding line and column, avoiding long absolute paths while preserving deterministic uniqueness. ## Testing - `dotnet test src\Controls\tests\BindingSourceGen.UnitTests\Controls.BindingSourceGen.UnitTests.csproj --no-restore --verbosity minimal` --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! Fixes #35857 Reviewer: @StephaneDelcroix ## Description The BindingSourceGen source generator used the full source file path as part of its generated source hint name. When `EmitCompilerGeneratedFiles` is enabled, Roslyn mirrors that hint name into the generated file path, which can exceed Windows `MAX_PATH` for projects in deeper directory structures. This changes the generated binding source hint name to use a compact stable hash of the source file path plus the binding line and column, avoiding long absolute paths while preserving deterministic uniqueness. ## Testing - `dotnet test src\Controls\tests\BindingSourceGen.UnitTests\Controls.BindingSourceGen.UnitTests.csproj --no-restore --verbosity minimal` --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! Fixes #35857 Reviewer: @StephaneDelcroix ## Description The BindingSourceGen source generator used the full source file path as part of its generated source hint name. When `EmitCompilerGeneratedFiles` is enabled, Roslyn mirrors that hint name into the generated file path, which can exceed Windows `MAX_PATH` for projects in deeper directory structures. This changes the generated binding source hint name to use a compact stable hash of the source file path plus the binding line and column, avoiding long absolute paths while preserving deterministic uniqueness. ## Testing - `dotnet test src\Controls\tests\BindingSourceGen.UnitTests\Controls.BindingSourceGen.UnitTests.csproj --no-restore --verbosity minimal` --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Fixes #35857
Reviewer: @StephaneDelcroix
Description
The BindingSourceGen source generator used the full source file path as part of its generated source hint name. When
EmitCompilerGeneratedFilesis enabled, Roslyn mirrors that hint name into the generated file path, which can exceed WindowsMAX_PATHfor projects in deeper directory structures.This changes the generated binding source hint name to use a compact stable hash of the source file path plus the binding line and column, avoiding long absolute paths while preserving deterministic uniqueness.
Testing
dotnet test src\Controls\tests\BindingSourceGen.UnitTests\Controls.BindingSourceGen.UnitTests.csproj --no-restore --verbosity minimal