private static List <BreakingChangeBase> CompareMethods(MethodData oldMethodBase, MethodData newMethodBase, AssemblyFamily newAssemblyFamily) { var breakingChanges = MetadataComparer.CompareItems(oldMethodBase, newMethodBase, newAssemblyFamily); MetadataComparer.CompareParameters(oldMethodBase, newMethodBase, newAssemblyFamily, breakingChanges); if (oldMethodBase.MetadataItemKind == MetadataItemKinds.Method) { var oldMethod = (MethodData)oldMethodBase; var newMethod = (MethodData)newMethodBase; if (oldMethod.GenericParameters.Count == newMethod.GenericParameters.Count) { for (int i = 0; i < oldMethod.GenericParameters.Count; i++) { breakingChanges.AddRange(MetadataComparer.CompareGenericTypeParameters(oldMethod.GenericParameters[i], newMethod.GenericParameters[i], newAssemblyFamily)); } } } return(breakingChanges); }
private static List <BreakingChangeBase> CompareTypes(TypeData oldTypeBase, TypeData newTypeBase, AssemblyFamily newAssemblyFamily) { var oldType = (TypeDefinitionData)oldTypeBase; var newType = (TypeDefinitionData)newTypeBase; var breakingChanges = MetadataComparer.CompareItems(oldType, newType, newAssemblyFamily); if (oldType.GenericParameters.Count == newType.GenericParameters.Count) { for (int i = 0; i < oldType.GenericParameters.Count; i++) { breakingChanges.AddRange(MetadataComparer.CompareGenericTypeParameters(oldType.GenericParameters[i], newType.GenericParameters[i], newAssemblyFamily)); } } var hasExternallyVisibleConstructor = oldType.GetMembers(".ctor").Count != 0; if (oldType.TypeKind != TypeKind.Delegate) { foreach (var oldMember in oldType.GetMembers()) { MemberDataBase newMember; if (oldType.TypeKind == TypeKind.Class && oldMember.IsOverride == false) { newMember = MetadataComparer.FindEquivalentMemberInClassHierarchy(oldMember, newType, newAssemblyFamily); } else { newMember = MetadataComparer.FindEquivalentMember(oldMember, newType, newAssemblyFamily); } if (newMember != null) { breakingChanges.AddRange(MetadataComparer.CompareMembers(oldMember, newMember, newAssemblyFamily)); continue; } if (MetadataComparer.IsMemberKindChangeAllowed(oldMember, newType, newAssemblyFamily)) { continue; } if (oldMember.IsOverride) { if (hasExternallyVisibleConstructor) { var baseMember = oldMember.GetBaseMember(); if (baseMember.IsAbstract) { breakingChanges.Add(new RemovedOverrideOfAbstractMember(oldMember, newType)); } } continue; } breakingChanges.Add(new RemovedMember(oldMember, newType)); } } switch (oldType.TypeKind) { case TypeKind.Class: foreach (var newMember in newType.GetMembers()) { if (newMember.IsAbstract) { var oldMember = MetadataComparer.FindEquivalentMemberInClassHierarchy(newMember, oldType, newAssemblyFamily); if (oldMember == null) { breakingChanges.Add(new AddedAbstractMember(newMember)); } } else if (newType.IsSealed == false && newMember.IsSealed && newMember.IsOverride) { // If the class contains a sealed override member, find the original equivalent member and see if derived // classes would have been able to override the member previously. var oldMember = MetadataComparer.FindEquivalentMemberInClassHierarchy(newMember, oldType, newAssemblyFamily); if (oldMember != null && oldMember.CanBeOverridden) { breakingChanges.Add(new SealedMember(oldMember, newMember)); } } } break; case TypeKind.Interface: foreach (var newMember in newType.GetMembers()) { var oldMember = MetadataComparer.FindEquivalentMember(newMember, oldType, newAssemblyFamily); if (oldMember == null) { breakingChanges.Add(new AddedInterfaceMember(newMember)); } } break; case TypeKind.Delegate: MetadataComparer.CompareParameters(oldType, newType, newAssemblyFamily, breakingChanges); break; } return(breakingChanges); }