/// <summary> /// Compare two types by recursively checking their properties and property /// types, making sure that nothing has been removed or changed. /// </summary> /// <param name="cmdlet">The cmdlet metadata currently being checked.</param> /// <param name="oldType">The type metadata from the old (serialized) assembly.</param> /// <param name="newType">The type metadata from the new assembly.</param> /// <param name="issueLogger">ReportLogger that will keep track of issues found.</param> public void CompareTypeMetadata( CmdletMetadata cmdlet, TypeMetadata oldType, TypeMetadata newType, ReportLogger <BreakingChangeIssue> issueLogger) { // For each property in the old assembly type, find the corresponding // property in the new assembly type foreach (var oldProperty in oldType.Properties.Keys) { if (newType.Properties.ContainsKey(oldProperty)) { var oldPropertyType = oldType.Properties[oldProperty]; var newPropertyType = newType.Properties[oldProperty]; var oldTypeMetadata = _oldTypeDictionary[oldPropertyType]; var newTypeMetadata = _newTypeDictionary[newPropertyType]; // Define variables for logging int problemId = ProblemIds.BreakingChangeProblemId.ChangedElementType; string description = string.Format(Properties.Resources.ChangedElementTypeDescription, oldProperty, oldTypeMetadata.ElementType, newTypeMetadata.ElementType); string remediation = string.Format(Properties.Resources.ChangedElementTypeRemediation, oldProperty, oldTypeMetadata.ElementType); // If the type is an array, check for any breaking changes if (IsElementType(cmdlet, oldTypeMetadata, newTypeMetadata, problemId, description, remediation, issueLogger)) { continue; } string target = string.Format("property {0}", oldProperty); // If the type is a generic, check for any breaking changes if (IsGenericType(cmdlet, oldTypeMetadata, newTypeMetadata, target, issueLogger)) { continue; } // If the types are the same, compare their properties if (oldPropertyType.Equals(newPropertyType, StringComparison.OrdinalIgnoreCase)) { // If we have not previously seen this type, run this // method on the type if (!_typeSet.Contains(oldPropertyType)) { _typeSet.Add(oldPropertyType); CompareTypeMetadata(cmdlet, oldTypeMetadata, newTypeMetadata, issueLogger); } } else { // If the type of the property has been changed, log an issue issueLogger.LogBreakingChangeIssue( cmdlet: cmdlet, severity: 0, problemId: ProblemIds.BreakingChangeProblemId.ChangedPropertyType, description: string.Format(Properties.Resources.ChangedPropertyTypeDescription, oldProperty, oldType.Name, oldPropertyType, newPropertyType), remediation: string.Format(Properties.Resources.ChangedPropertyTypeRemediation, oldProperty, oldPropertyType)); } } else { // If the property has been removed, log an issue issueLogger.LogBreakingChangeIssue( cmdlet: cmdlet, severity: 0, problemId: ProblemIds.BreakingChangeProblemId.RemovedProperty, description: string.Format(Properties.Resources.RemovedPropertyDescription, oldProperty, oldType.Name), remediation: string.Format(Properties.Resources.RemovedPropertyRemediation, oldProperty, oldType.Name)); } } }