@@ -1261,62 +1261,51 @@ protected override ScmMethodProvider[] BuildMethods()
12611261
12621262 protected sealed override IReadOnlyList < MethodProvider > BuildMethodsForBackCompatibility ( IEnumerable < MethodProvider > originalMethods )
12631263 {
1264- List < MethodProvider > materializedMethods = [ .. originalMethods ] ;
1265-
12661264 if ( LastContractView ? . Methods == null || LastContractView . Methods . Count == 0 )
12671265 {
1268- return materializedMethods ;
1266+ return [ .. originalMethods ] ;
12691267 }
12701268
1271- var currentMethodSignatures = BuildCurrentMethodSignatures ( materializedMethods ) ;
1272-
1273- ProcessBackCompatForParameterReordering ( materializedMethods , currentMethodSignatures ) ;
1274- ProcessBackCompatForNewOptionalParameters ( materializedMethods , currentMethodSignatures ) ;
1269+ // Snapshot the current signatures before the base reorders any of them in place, so we
1270+ // can fix up convenience method bodies that call reordered protocol methods afterwards.
1271+ var originalSignatures = new Dictionary < MethodProvider , MethodSignature > ( ReferenceEqualityComparer . Instance ) ;
1272+ foreach ( var method in originalMethods )
1273+ {
1274+ originalSignatures . TryAdd ( method , method . Signature ) ;
1275+ }
12751276
1276- return materializedMethods ;
1277- }
1277+ List < MethodProvider > result = [ .. base . BuildMethodsForBackCompatibility ( originalMethods ) ] ;
12781278
1279- private void ProcessBackCompatForParameterReordering (
1280- IList < MethodProvider > materializedMethods ,
1281- Dictionary < MethodSignature , MethodProvider > currentMethodSignatures )
1282- {
1279+ // Determine which existing methods had their parameters reordered by the base and fix up
1280+ // convenience method bodies that call the reordered protocol methods.
12831281 var updatedSignatureToOriginal = new Dictionary < MethodSignature , MethodSignature > ( MethodSignature . MethodSignatureComparer ) ;
12841282 var methodsWithReorderedParams = new List < MethodProvider > ( ) ;
1285-
1286- foreach ( var previousMethod in LastContractView ! . Methods )
1283+ foreach ( var ( method , originalSignature ) in originalSignatures )
12871284 {
1288- if ( ! ShouldProcessMethodForBackCompat ( previousMethod . Signature , currentMethodSignatures ) )
1285+ if ( method . Signature . Name . Equals ( originalSignature . Name )
1286+ && ! MethodSignatureHelper . HaveSameParametersInSameOrder ( method . Signature , originalSignature ) )
12891287 {
1290- continue ;
1291- }
1292-
1293- var methodToUpdate = FindMethodWithSameParametersButDifferentOrder (
1294- previousMethod . Signature ,
1295- currentMethodSignatures ) ;
1296-
1297- if ( methodToUpdate != null && TryReorderCurrentMethodParameters (
1298- methodToUpdate ,
1299- previousMethod . Signature ,
1300- updatedSignatureToOriginal ) )
1301- {
1302- methodsWithReorderedParams . Add ( methodToUpdate ) ;
1303- CodeModelGenerator . Instance . Emitter . Debug (
1304- $ "Reordered parameters of '{ Name } .{ methodToUpdate . Signature . Name } ' to match last contract.",
1305- BackCompatibilityChangeCategory . MethodParameterReordering ) ;
1288+ updatedSignatureToOriginal . TryAdd ( method . Signature , originalSignature ) ;
1289+ methodsWithReorderedParams . Add ( method ) ;
13061290 }
13071291 }
13081292
13091293 if ( methodsWithReorderedParams . Count > 0 )
13101294 {
1311- UpdateConvenienceMethodsForBackCompat ( materializedMethods , methodsWithReorderedParams , updatedSignatureToOriginal ) ;
1295+ UpdateConvenienceMethodsForBackCompat ( result , methodsWithReorderedParams , updatedSignatureToOriginal ) ;
13121296 }
1297+
1298+ // Add hidden overloads for methods that gained new optional non-body parameters.
1299+ ProcessBackCompatForNewOptionalParameters ( result , BuildCurrentMethodSignatureMap ( result ) ) ;
1300+
1301+ return result ;
13131302 }
13141303
1315- private Dictionary < MethodSignature , MethodProvider > BuildCurrentMethodSignatures ( IEnumerable < MethodProvider > originalMethods )
1304+ private Dictionary < MethodSignature , MethodProvider > BuildCurrentMethodSignatureMap ( IEnumerable < MethodProvider > methods )
13161305 {
13171306 var allMethods = CustomCodeView ? . Methods != null
1318- ? originalMethods . Concat ( CustomCodeView . Methods )
1319- : originalMethods ;
1307+ ? methods . Concat ( CustomCodeView . Methods )
1308+ : methods ;
13201309
13211310 var result = new Dictionary < MethodSignature , MethodProvider > ( MethodSignature . MethodSignatureComparer ) ;
13221311 foreach ( var method in allMethods )
@@ -1326,86 +1315,6 @@ private Dictionary<MethodSignature, MethodProvider> BuildCurrentMethodSignatures
13261315 return result ;
13271316 }
13281317
1329- private static bool ShouldProcessMethodForBackCompat (
1330- MethodSignature previousSignature ,
1331- Dictionary < MethodSignature , MethodProvider > currentMethodSignatures )
1332- {
1333- if ( currentMethodSignatures . ContainsKey ( previousSignature ) )
1334- {
1335- return false ;
1336- }
1337-
1338- var modifiers = previousSignature . Modifiers ;
1339- return modifiers . HasFlag ( MethodSignatureModifiers . Public ) ||
1340- modifiers . HasFlag ( MethodSignatureModifiers . Protected ) ;
1341- }
1342-
1343- private static MethodProvider ? FindMethodWithSameParametersButDifferentOrder (
1344- MethodSignature previousSignature ,
1345- Dictionary < MethodSignature , MethodProvider > currentMethodSignatures )
1346- {
1347- foreach ( var kvp in currentMethodSignatures )
1348- {
1349- var currentSignature = kvp . Key ;
1350- if ( currentSignature . Name . Equals ( previousSignature . Name )
1351- && currentSignature . ReturnType ? . AreNamesEqual ( previousSignature . ReturnType ) == true
1352- && MethodSignatureHelper . ContainsSameParameters ( previousSignature , currentSignature ) )
1353- {
1354- return kvp . Value ;
1355- }
1356- }
1357-
1358- return null ;
1359- }
1360-
1361- private bool TryReorderCurrentMethodParameters (
1362- MethodProvider methodToUpdate ,
1363- MethodSignature previousSignature ,
1364- Dictionary < MethodSignature , MethodSignature > updatedSignatureToOriginal )
1365- {
1366- var currentSignature = methodToUpdate . Signature ;
1367- // Early exit: Check if parameters are already in the same order
1368- if ( MethodSignatureHelper . HaveSameParametersInSameOrder ( currentSignature , previousSignature ) )
1369- {
1370- return false ;
1371- }
1372-
1373- var parametersByName = currentSignature . Parameters . ToDictionary ( p => p . Name . ToVariableName ( ) ) ;
1374- var reorderedParameters = new List < ParameterProvider > ( currentSignature . Parameters . Count ) ;
1375-
1376- foreach ( var previousParam in previousSignature . Parameters )
1377- {
1378- if ( parametersByName . TryGetValue ( previousParam . Name , out var matchingParam ) )
1379- {
1380- reorderedParameters . Add ( matchingParam ) ;
1381- }
1382- }
1383-
1384- if ( reorderedParameters . Count != currentSignature . Parameters . Count )
1385- {
1386- return false ;
1387- }
1388-
1389- var updatedSignature = new MethodSignature (
1390- currentSignature . Name ,
1391- currentSignature . Description ,
1392- currentSignature . Modifiers ,
1393- currentSignature . ReturnType ,
1394- currentSignature . ReturnDescription ,
1395- reorderedParameters ,
1396- currentSignature . Attributes ,
1397- currentSignature . GenericArguments ,
1398- currentSignature . GenericParameterConstraints ,
1399- currentSignature . ExplicitInterface ,
1400- currentSignature . NonDocumentComment ) ;
1401- updatedSignatureToOriginal . TryAdd ( updatedSignature , currentSignature ) ;
1402-
1403- UpdateXmlDocProviderForParamReorder ( methodToUpdate . XmlDocs , updatedSignature ) ;
1404- methodToUpdate . Update ( signature : updatedSignature , xmlDocProvider : methodToUpdate . XmlDocs ) ;
1405-
1406- return true ;
1407- }
1408-
14091318 private ParameterProvider BuildClientEndpointParameter ( )
14101319 {
14111320 _inputEndpointParam = _inputClient . Parameters
@@ -1743,28 +1652,6 @@ private static void ReorderMethodInvocationArguments(
17431652 }
17441653 }
17451654
1746- private static void UpdateXmlDocProviderForParamReorder (
1747- XmlDocProvider xmlDocs ,
1748- MethodSignature updatedSignature )
1749- {
1750- var paramDocsByName = xmlDocs . Parameters . ToDictionary ( s => s . Parameter . Name ) ;
1751- var reorderedParamDocs = new List < XmlDocParamStatement > ( updatedSignature . Parameters . Count ) ;
1752-
1753- foreach ( var param in updatedSignature . Parameters )
1754- {
1755- if ( paramDocsByName . TryGetValue ( param . Name , out var paramDoc ) )
1756- {
1757- reorderedParamDocs . Add ( paramDoc ) ;
1758- }
1759- }
1760-
1761- if ( reorderedParamDocs . Count == xmlDocs . Parameters . Count &&
1762- ! reorderedParamDocs . SequenceEqual ( xmlDocs . Parameters ) )
1763- {
1764- xmlDocs . Update ( parameters : reorderedParamDocs ) ;
1765- }
1766- }
1767-
17681655 private void ProcessBackCompatForNewOptionalParameters (
17691656 List < MethodProvider > methods ,
17701657 Dictionary < MethodSignature , MethodProvider > currentMethodSignatures )
0 commit comments