| File: ChangeSignature\SignatureChange.cs | Web Access |
| Project: src\roslyn\src\Features\Core\Portable\Microsoft.CodeAnalysis.Features.csproj (Microsoft.CodeAnalysis.Features) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis.Shared.Extensions; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.ChangeSignature; internal sealed class SignatureChange { public readonly ParameterConfiguration OriginalConfiguration; public readonly ParameterConfiguration UpdatedConfiguration; private readonly Dictionary<int, int?> _originalIndexToUpdatedIndexMap = []; public SignatureChange(ParameterConfiguration originalConfiguration, ParameterConfiguration updatedConfiguration) { OriginalConfiguration = originalConfiguration; UpdatedConfiguration = updatedConfiguration; // TODO: Could be better than O(n^2) var originalParameterList = originalConfiguration.ToListOfParameters(); var updatedParameterList = updatedConfiguration.ToListOfParameters(); for (var i = 0; i < originalParameterList.Length; i++) { int? index = null; var parameter = originalParameterList[i]; if (parameter is ExistingParameter existingParameter) { var updatedIndex = updatedParameterList.IndexOf(p => p is ExistingParameter ep && ep.Symbol.Equals(existingParameter.Symbol)); if (updatedIndex >= 0) { index = updatedIndex; } } _originalIndexToUpdatedIndexMap.Add(i, index); } } public int? GetUpdatedIndex(int parameterIndex) { if (parameterIndex >= OriginalConfiguration.ToListOfParameters().Length) { return null; } return _originalIndexToUpdatedIndexMap[parameterIndex]; } internal SignatureChange WithoutAddedParameters() => new(OriginalConfiguration, UpdatedConfiguration.WithoutAddedParameters()); internal void LogTelemetry() { var originalListOfParameters = OriginalConfiguration.ToListOfParameters(); var updatedListOfParameters = UpdatedConfiguration.ToListOfParameters(); ChangeSignatureLogger.LogTransformationInformation( numOriginalParameters: originalListOfParameters.Length, numParametersAdded: updatedListOfParameters.Count(p => p is AddedParameter), numParametersRemoved: originalListOfParameters.Count(p => !updatedListOfParameters.Contains(p)), anyParametersReordered: AnyParametersReordered(originalListOfParameters, updatedListOfParameters)); foreach (var addedParameter in updatedListOfParameters.OfType<AddedParameter>()) { if (addedParameter.IsRequired) { ChangeSignatureLogger.LogAddedParameterRequired(); } if (addedParameter.TypeBinds) { ChangeSignatureLogger.LogAddedParameterTypeBinds(); } if (addedParameter.CallSiteKind == CallSiteKind.Todo) { ChangeSignatureLogger.LogAddedParameter_ValueTODO(); } else if (addedParameter.CallSiteKind == CallSiteKind.Omitted) { ChangeSignatureLogger.LogAddedParameter_ValueOmitted(); } else { if (addedParameter.CallSiteKind == CallSiteKind.ValueWithName) { ChangeSignatureLogger.LogAddedParameter_ValueExplicitNamed(); } else { ChangeSignatureLogger.LogAddedParameter_ValueExplicit(); } } } } private static bool AnyParametersReordered(ImmutableArray<Parameter> originalListOfParameters, ImmutableArray<Parameter> updatedListOfParameters) { var originalListWithoutRemovedOrAdded = originalListOfParameters.WhereAsArray(updatedListOfParameters.Contains); var updatedListWithoutRemovedOrAdded = updatedListOfParameters.WhereAsArray(originalListOfParameters.Contains); for (var i = 0; i < originalListWithoutRemovedOrAdded.Length; i++) { if (originalListWithoutRemovedOrAdded[i] != updatedListWithoutRemovedOrAdded[i]) { return true; } } return false; } }