private static List <BreakingChangeBase> CompareIndexers(IndexerData oldIndexer, IndexerData newIndexer, AssemblyFamily newAssemblyFamily)
        {
            var breakingChanges = MetadataComparer.CompareItems(oldIndexer, newIndexer, newAssemblyFamily);

            MetadataComparer.CompareParameters(oldIndexer, newIndexer, newAssemblyFamily, breakingChanges);
            return(breakingChanges);
        }
 private static void CompareParameters(IParameterizedItem oldParameterizedItem, IParameterizedItem newParameterizedItem, AssemblyFamily newAssemblyFamily, List <BreakingChangeBase> breakingChanges)
 {
     if (oldParameterizedItem.Parameters.Count == newParameterizedItem.Parameters.Count)
     {
         for (int i = 0; i < oldParameterizedItem.Parameters.Count; i++)
         {
             breakingChanges.AddRange(MetadataComparer.CompareParameters(oldParameterizedItem.Parameters[i], newParameterizedItem.Parameters[i], newAssemblyFamily, (MetadataItemBase)newParameterizedItem));
         }
     }
 }
        private static List <BreakingChangeBase> CompareParameters(ParameterData oldParameter, ParameterData newParameter, AssemblyFamily newAssemblyFamily, MetadataItemBase declaringMember)
        {
            var breakingChanges = MetadataComparer.CompareItems(oldParameter, newParameter, newAssemblyFamily, declaringMember);

            // If a parameter is changed completely, it will most likely have a new type and name. We should only warn about the type change.
            var typeChanges = new HashSet <ParameterData>(
                breakingChanges.OfType <ChangedParameterType>().Select(b => b.NewParameter)
                );

            breakingChanges.RemoveAll(b => b.BreakingChangeKind == BreakingChangeKind.ChangedParameterName && typeChanges.Contains((ParameterData)b.NewItem));

            return(breakingChanges);
        }
        private static List <BreakingChangeBase> CompareAssemblies(AssemblyData oldAssembly, AssemblyData newAssembly, AssemblyFamily newFamily)
        {
            var breakingChanges = new List <BreakingChangeBase>();

            foreach (var oldType in oldAssembly.GetNonNestedTypeDefinitions())
            {
                var newType = oldType.GetEquivalentNewType(newFamily);
                if (newType == null)
                {
                    breakingChanges.Add(new RemovedRootType(oldType));
                }
                else
                {
                    breakingChanges.AddRange(MetadataComparer.CompareTypes(oldType, newType, newFamily));
                }
            }
            return(breakingChanges);
        }
        private static MemberDataBase FindEquivalentMemberInClassHierarchy(MemberDataBase oldMember, DeclaringTypeData newType, AssemblyFamily newAssemblyFamily)
        {
            var allowMatchOnNameOnly = true;
            var current = newType;

            while (current != null)
            {
                var newMember = MetadataComparer.FindEquivalentMember(oldMember, current, newAssemblyFamily, allowMatchOnNameOnly);
                if (newMember != null)
                {
                    return(newMember);
                }

                current = current.BaseType;
                allowMatchOnNameOnly = false;
            }

            return(null);
        }
        /// <summary>
        /// Compares two <see cref="AssemblyFamily"/> instances and returns the breaking changes introduced in the newer assemblies if their
        /// associated older versions exist in the <paramref name="oldFamily"/>.
        /// </summary>
        public static List <BreakingChangeBase> CompareAssemblyFamilies(AssemblyFamily oldFamily, AssemblyFamily newFamily)
        {
            var breakingChanges = new List <BreakingChangeBase>();

            foreach (var oldAssembly in oldFamily)
            {
                var newAssembly = newFamily.GetEquivalentAssembly(oldAssembly);
                if (newAssembly == null)
                {
                    breakingChanges.Add(new RemovedAssembly(oldAssembly));
                }
                else
                {
                    breakingChanges.AddRange(MetadataComparer.CompareAssemblies(oldAssembly, newAssembly, newFamily));
                }
            }

            return(breakingChanges);
        }
        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 IEnumerable <BreakingChangeBase> CompareMembers(MemberDataBase oldMember, MemberDataBase newMember, AssemblyFamily newAssemblyFamily)
        {
            switch (oldMember.MetadataItemKind)
            {
            case MetadataItemKinds.Constant:
            case MetadataItemKinds.Event:
            case MetadataItemKinds.Field:
            case MetadataItemKinds.Property:
                return(MetadataComparer.CompareItems(oldMember, newMember, newAssemblyFamily));

            case MetadataItemKinds.Indexer:
                return(MetadataComparer.CompareIndexers((IndexerData)oldMember, (IndexerData)newMember, newAssemblyFamily));

            case MetadataItemKinds.Constructor:
            case MetadataItemKinds.Operator:
            {
                var breakingChanges = MetadataComparer.CompareItems(oldMember, newMember, newAssemblyFamily);
                MetadataComparer.CompareParameters((IParameterizedItem)oldMember, (IParameterizedItem)newMember, newAssemblyFamily, breakingChanges);
                return(breakingChanges);
            }

            case MetadataItemKinds.Method:
                return(MetadataComparer.CompareMethods((MethodData)oldMember, (MethodData)newMember, newAssemblyFamily));

            case MetadataItemKinds.TypeDefinition:
                return(MetadataComparer.CompareTypes((TypeDefinitionData)oldMember, (TypeDefinitionData)newMember, newAssemblyFamily));

            case MetadataItemKinds.Assembly:
            case MetadataItemKinds.GenericTypeParameter:
            case MetadataItemKinds.Parameter:
                Debug.Fail("This is not a member: " + oldMember.MetadataItemKind);
                break;

            default:
                Debug.Fail("Unknown MetadataItemKinds: " + oldMember.MetadataItemKind);
                break;
            }

            return(_noBreakingChanges);
        }
        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);
        }
 private static List <BreakingChangeBase> CompareGenericTypeParameters(GenericTypeParameterData oldGenericTypeParameter, GenericTypeParameterData newGenericTypeParameter, AssemblyFamily newAssemblyFamily)
 {
     return(MetadataComparer.CompareItems(oldGenericTypeParameter, newGenericTypeParameter, newAssemblyFamily));
 }
 /// <summary>
 /// Compares two associated <see cref="TypeData"/> instances and returns the breaking changes introduced in the newer version of the
 /// type.
 /// </summary>
 public static List <BreakingChangeBase> CompareTypes(TypeData oldTypeBase, TypeData newTypeBase)
 {
     return(MetadataComparer.CompareTypes(oldTypeBase, newTypeBase, newTypeBase.GetDefiningAssemblyFamily()));
 }
 /// <summary>
 /// Compares two associated <see cref="AssemblyData"/> instances and returns the breaking changes introduced in the newer version of
 /// the assembly.
 /// </summary>
 public static List <BreakingChangeBase> CompareAssemblies(AssemblyData oldAssembly, AssemblyData newAssembly)
 {
     return(MetadataComparer.CompareAssemblies(oldAssembly, newAssembly, new AssemblyFamily {
         newAssembly
     }));
 }