public override void CompareItems(CompareItemsContext context)
        {
            var oldType = (TypeDefinitionData)context.OldItem;
            var newType = (TypeDefinitionData)context.NewItem;

            if (oldType.TypeKind != TypeKind.Interface)
            {
                return;
            }

            foreach (var newInterfaceType in newType.ImplementedInterfaces)
            {
                if (newInterfaceType.HasMembers == false)
                {
                    continue;
                }

                var hasNewInterfaceEquivalent = false;
                foreach (var oldInterfaceType in oldType.ImplementedInterfaces)
                {
                    if (oldInterfaceType.IsEquivalentToNew(newInterfaceType, context.NewAssemblyFamily))
                    {
                        hasNewInterfaceEquivalent = true;
                        break;
                    }
                }

                if (hasNewInterfaceEquivalent == false)
                {
                    context.BreakingChanges.Add(new AddedBaseInterface(oldType, newType, newInterfaceType));
                }
            }
        }
Exemple #2
0
        public override void CompareItems(CompareItemsContext context)
        {
            var oldParameter = (ParameterData)context.OldItem;
            var newParameter = (ParameterData)context.NewItem;

            if (oldParameter.IsTypeDynamic == newParameter.IsTypeDynamic && oldParameter.Type.IsEquivalentToNew(newParameter.Type, context.NewAssemblyFamily))
            {
                return;
            }

            var isBreakingChange = false;

            if (oldParameter.Modifer != ParameterModifier.None)
            {
                isBreakingChange = true;
            }
            else if (newParameter.IsTypeDynamic == false)
            {
                isBreakingChange = (oldParameter.IsTypeDynamic || newParameter.Type.IsAssignableFromOld(oldParameter.Type, context.NewAssemblyFamily) == false);
            }

            if (isBreakingChange)
            {
                context.BreakingChanges.Add(new ChangedParameterType(oldParameter, newParameter, (IParameterizedItem)context.AdditionalInfo));
            }
        }
Exemple #3
0
        public override void CompareItems(CompareItemsContext context)
        {
            var oldParameterizedItem = (IParameterizedItem)context.OldItem;
            var newParameterizedItem = (IParameterizedItem)context.NewItem;

            if (oldParameterizedItem.Parameters == null || newParameterizedItem.Parameters == null)
            {
                return;
            }

            // If there are now fewer parameters than before, it could be breaking, because someone could have specified all parameters
            if (newParameterizedItem.Parameters.Count < oldParameterizedItem.Parameters.Count)
            {
                context.BreakingChanges.Add(new ChangedParameterCount(oldParameterizedItem, newParameterizedItem));
                return;
            }

            // If there are now more required parameters than before, it could be breaking, because someone could have specified the minimum
            // required parameters before, which is no longer valid.
            if (oldParameterizedItem.Parameters.RequiredArgumentCount < newParameterizedItem.Parameters.RequiredArgumentCount)
            {
                context.BreakingChanges.Add(new ChangedParameterCount(oldParameterizedItem, newParameterizedItem));
                return;
            }
        }
Exemple #4
0
        public override void CompareItems(CompareItemsContext context)
        {
            var oldParameter = (ParameterData)context.OldItem;
            var newParameter = (ParameterData)context.NewItem;

            if (oldParameter.DeclaringMemberKind != MetadataItemKinds.Operator && oldParameter.Name != newParameter.Name)
            {
                context.BreakingChanges.Add(new ChangedParameterName(oldParameter, newParameter, (IParameterizedItem)context.AdditionalInfo));
            }
        }
Exemple #5
0
        public override void CompareItems(CompareItemsContext context)
        {
            var oldMethod = (MethodData)context.OldItem;
            var newMethod = (MethodData)context.NewItem;

            if (oldMethod.IsExtensionMethod && newMethod.IsExtensionMethod == false)
            {
                context.BreakingChanges.Add(new RemovedExtensionMethodModifier(oldMethod, newMethod));
            }
        }
        public override void CompareItems(CompareItemsContext context)
        {
            var oldField = (FieldData)context.OldItem;
            var newField = (FieldData)context.NewItem;

            if (oldField.IsReadOnly == false && newField.IsReadOnly)
            {
                context.BreakingChanges.Add(new ChangedFieldToReadOnly(oldField, newField));
            }
        }
        public override void CompareItems(CompareItemsContext context)
        {
            var oldMember = (MemberDataBase)context.OldItem;
            var newMember = (MemberDataBase)context.NewItem;

            if (oldMember.IsVirtualCallType && newMember.IsVirtualCallType == false)
            {
                context.BreakingChanges.Add(new ChangedMemberToNonVirtual(oldMember, newMember));
            }
        }
        public override void CompareItems(CompareItemsContext context)
        {
            var oldMember = (MemberDataBase)context.OldItem;
            var newMember = (MemberDataBase)context.NewItem;

            if (oldMember.IsAbstract == false && newMember.IsAbstract)
            {
                context.BreakingChanges.Add(new ChangedMemberToAbstract(oldMember, newMember));
            }
        }
        public override void CompareItems(CompareItemsContext context)
        {
            var oldParameter = (ParameterData)context.OldItem;
            var newParameter = (ParameterData)context.NewItem;

            if (oldParameter.Modifer != newParameter.Modifer)
            {
                context.BreakingChanges.Add(new ChangedParameterModifier(oldParameter, newParameter, (IParameterizedItem)context.AdditionalInfo));
            }
        }
Exemple #10
0
        public override void CompareItems(CompareItemsContext context)
        {
            var oldType = (TypeDefinitionData)context.OldItem;
            var newType = (TypeDefinitionData)context.NewItem;

            if (oldType.HasPublicConstructors && oldType.IsAbstract == false && newType.IsAbstract)
            {
                context.BreakingChanges.Add(new ChangedClassToAbstract(oldType, newType));
            }
        }
        public override void CompareItems(CompareItemsContext context)
        {
            var oldMember = (MemberDataBase)context.OldItem;
            var newMember = (MemberDataBase)context.NewItem;

            if (oldMember.IsInstance != newMember.IsInstance)
            {
                context.BreakingChanges.Add(new ChangedStaticOrInstanceStatus(oldMember, newMember));
            }
        }
Exemple #12
0
        public override void CompareItems(CompareItemsContext context)
        {
            var oldTypedItem = (ITypedItem)context.OldItem;
            var newTypedItem = (ITypedItem)context.NewItem;

            if (oldTypedItem.Type == null || newTypedItem.Type == null)
            {
                return;
            }

            // Changing from void to non-void is allowed.
            var typeDefinition = oldTypedItem.Type as TypeDefinitionData;

            if (typeDefinition != null &&
                typeDefinition.FullName == Utilities.VoidTypeName &&
                typeDefinition.AssemblyData.Name == Utilities.CommonObjectRuntimeAssemblyName)
            {
                return;
            }

            // If we are comparing two enum members, we know they came from the same type, which is also their return type, so we don't need to check below.
            if (context.OldItem.MetadataItemKind == MetadataItemKinds.Constant &&
                ((MemberDataBase)context.OldItem).DeclaringType.TypeKind == TypeKind.Enum)
            {
                return;
            }

            switch (context.OldItem.MetadataItemKind)
            {
            // Read/write fields cannot change type at all because they can be used in out or ref parameters
            case MetadataItemKinds.Field:
                if (((FieldData)context.OldItem).IsReadOnly)
                {
                    goto default;
                }

                if (oldTypedItem.IsTypeDynamic != newTypedItem.IsTypeDynamic ||
                    oldTypedItem.Type.IsEquivalentToNew(newTypedItem.Type, context.NewAssemblyFamily) == false)
                {
                    context.BreakingChanges.Add(new ChangedMemberType(oldTypedItem, newTypedItem));
                }
                break;

            default:
                if (newTypedItem.IsTypeDynamic == false)
                {
                    if (oldTypedItem.IsTypeDynamic || oldTypedItem.Type.IsAssignableFromNew(newTypedItem.Type, context.NewAssemblyFamily) == false)
                    {
                        context.BreakingChanges.Add(new ChangedMemberType(oldTypedItem, newTypedItem));
                    }
                }
                break;
            }
        }
Exemple #13
0
        public override void CompareItems(CompareItemsContext context)
        {
            var oldType = (TypeDefinitionData)context.OldItem;
            var newType = (TypeDefinitionData)context.NewItem;

            if (oldType.GetMembers(".ctor").Count != 0 &&
                oldType.IsSealed == false && newType.IsSealed)
            {
                context.BreakingChanges.Add(new SealedClass(oldType, newType));
            }
        }
        public override void CompareItems(CompareItemsContext context)
        {
            var oldMember = (MemberDataBase)context.OldItem;
            var newMember = (MemberDataBase)context.NewItem;

            if (oldMember.Accessibility == MemberAccessibility.Public &&
                newMember.Accessibility == MemberAccessibility.Protected)
            {
                context.BreakingChanges.Add(new ChangedAccessibilityFromPublicToProtected(oldMember, newMember));
            }
        }
        public override void CompareItems(CompareItemsContext context)
        {
            var oldParameter = (ParameterData)context.OldItem;
            var newParameter = (ParameterData)context.NewItem;

            if (oldParameter.IsOptional &&
                newParameter.IsOptional &&
                Object.Equals(oldParameter.DefaultValue, newParameter.DefaultValue) == false)
            {
                context.BreakingChanges.Add(new ChangedParameterDefaultValue(oldParameter, newParameter, (IParameterizedItem)context.AdditionalInfo));
            }
        }
Exemple #16
0
        public override void CompareItems(CompareItemsContext context)
        {
            var oldType = (TypeDefinitionData)context.OldItem;
            var newType = (TypeDefinitionData)context.NewItem;

            if (oldType.IsStatic == false && newType.IsStatic)
            {
                if (oldType.HasPublicConstructors || oldType.CanBeInherited)
                {
                    context.BreakingChanges.Add(new ChangedClassToStatic(oldType, newType));
                }
            }
        }
        public override void CompareItems(CompareItemsContext context)
        {
            var oldGenericParameter = (GenericTypeParameterData)context.OldItem;
            var newGenericParameter = (GenericTypeParameterData)context.NewItem;

            var oldVarianceAttributes = oldGenericParameter.GenericParameterAttributes & GenericParameterAttributes.VarianceMask;
            var newVarianceAttributes = newGenericParameter.GenericParameterAttributes & GenericParameterAttributes.VarianceMask;

            if (oldVarianceAttributes != GenericParameterAttributes.None && oldVarianceAttributes != newVarianceAttributes)
            {
                context.BreakingChanges.Add(new ChangedGenericTypeParameterVariance(oldGenericParameter, newGenericParameter));
            }
        }
        public override void CompareItems(CompareItemsContext context)
        {
            var oldType = (TypeDefinitionData)context.OldItem;
            var newType = (TypeDefinitionData)context.NewItem;

            // If the old type is object, the new type will be derived from it, so there are no breaking changes.
            if (oldType.BaseType != null)
            {
                if (oldType.TypeKind == TypeKind.Class && oldType.BaseType.IsAssignableFromNew(newType.BaseType, context.NewAssemblyFamily) == false)
                {
                    context.BreakingChanges.Add(new IncompatibleClassHierarchy(oldType, newType));
                }
            }
        }
Exemple #19
0
        public override void CompareItems(CompareItemsContext context)
        {
            var oldProperty = (PropertyData)context.OldItem;
            var newProperty = (PropertyData)context.NewItem;

            if ((oldProperty.GetMethodAccessibility != null && newProperty.GetMethodAccessibility == null) ||
                (oldProperty.Accessibility == newProperty.Accessibility && oldProperty.GetMethodAccessibility == MemberAccessibility.Public && newProperty.GetMethodAccessibility == MemberAccessibility.Protected))
            {
                context.BreakingChanges.Add(new RemovedPropertyAccessors(oldProperty, newProperty));
                return;
            }

            if ((oldProperty.SetMethodAccessibility != null && newProperty.SetMethodAccessibility == null) ||
                (oldProperty.Accessibility == newProperty.Accessibility && oldProperty.SetMethodAccessibility == MemberAccessibility.Public && newProperty.SetMethodAccessibility == MemberAccessibility.Protected))
            {
                context.BreakingChanges.Add(new RemovedPropertyAccessors(oldProperty, newProperty));
            }
        }
        public override void CompareItems(CompareItemsContext context)
        {
            var oldProperty = (PropertyData)context.OldItem;
            var newProperty = (PropertyData)context.NewItem;

            // TODO: What about protected accessors that are made internal/private. This doesn't seem to check for it. Do we handle it somewhere else?
            if ((oldProperty.GetMethodAccessibility != null && newProperty.GetMethodAccessibility == null) ||
                (oldProperty.Accessibility == newProperty.Accessibility && oldProperty.GetMethodAccessibility == Accessibility.Public && newProperty.GetMethodAccessibility != Accessibility.Public))
            {
                context.BreakingChanges.Add(new RemovedPropertyAccessors(oldProperty, newProperty));
                return;
            }

            if ((oldProperty.SetMethodAccessibility != null && newProperty.SetMethodAccessibility == null) ||
                (oldProperty.Accessibility == newProperty.Accessibility && oldProperty.SetMethodAccessibility == Accessibility.Public && newProperty.SetMethodAccessibility != Accessibility.Public))
            {
                context.BreakingChanges.Add(new RemovedPropertyAccessors(oldProperty, newProperty));
            }
        }
Exemple #21
0
        public override void CompareItems(CompareItemsContext context)
        {
            var oldGenericParameter = (GenericTypeParameterData)context.OldItem;
            var newGenericParameter = (GenericTypeParameterData)context.NewItem;

            var oldConstraintAttributes = oldGenericParameter.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
            var newConstraintAttributes = newGenericParameter.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;

            bool haveConstraintsChanged = (oldConstraintAttributes != newConstraintAttributes);

            if (haveConstraintsChanged == false)
            {
                foreach (var oldContraintType in oldGenericParameter.Constraints)
                {
                    if (newGenericParameter.Constraints.Any(c => oldContraintType.IsEquivalentToNew(c, context.NewAssemblyFamily)) == false)
                    {
                        haveConstraintsChanged = true;
                        break;
                    }
                }

                if (haveConstraintsChanged == false)
                {
                    foreach (var newContraintType in newGenericParameter.Constraints)
                    {
                        if (oldGenericParameter.Constraints.Any(c => newContraintType.IsEquivalentToOld(c, context.NewAssemblyFamily)) == false)
                        {
                            haveConstraintsChanged = true;
                            break;
                        }
                    }
                }
            }

            if (haveConstraintsChanged)
            {
                context.BreakingChanges.Add(new ChangedGenericTypeParameterConstraints(oldGenericParameter, newGenericParameter));
            }
        }
        public override void CompareItems(CompareItemsContext context)
        {
            var oldType = (TypeDefinitionData)context.OldItem;
            var newType = (TypeDefinitionData)context.NewItem;

            foreach (var oldInterfaceType in oldType.ImplementedInterfaces)
            {
                var hasOldInterfaceEquivalent = false;
                foreach (var newInterfaceType in newType.ImplementedInterfaces)
                {
                    if (oldInterfaceType.IsAssignableFromNew(newInterfaceType, context.NewAssemblyFamily))
                    {
                        hasOldInterfaceEquivalent = true;
                        break;
                    }
                }

                if (hasOldInterfaceEquivalent == false)
                {
                    context.BreakingChanges.Add(new RemovedImplementedInterface(oldType, newType, oldInterfaceType));
                }
            }
        }
Exemple #23
0
 public abstract void CompareItems(CompareItemsContext context);