public override DifferenceType Diff(IDifferences differences, Mappings.MemberMapping mapping)
        {
            ITypeDefinitionMember impl     = mapping[0];
            ITypeDefinitionMember contract = mapping[1];

            if (impl == null)
            {
                return(DifferenceType.Unknown);
            }

            if (contract == null && impl.IsAbstract())
            {
                // If the type is effectively sealed then it is ok to remove abstract members
                ITypeDefinition contractType = mapping.ContainingType[1];
                // We check that interfaces have the same number of members in another rule so there is no need to check that here.
                if (contractType != null && (contractType.IsEffectivelySealed() || (contractType.IsInterface && mapping.ContainingType[0].IsInterface)))
                {
                    return(DifferenceType.Unknown);
                }

                differences.AddIncompatibleDifference(this, impl.GetMemberViolationMessage("Member", $"is abstract in the {Implementation}", $"is missing in the {Contract}"));
                return(DifferenceType.Changed);
            }
            return(DifferenceType.Unknown);
        }
        public virtual bool Include(ITypeDefinitionMember member)
        {
            switch (member.Visibility)
            {
            case TypeMemberVisibility.Public:
                return(true);

            case TypeMemberVisibility.Family:
            case TypeMemberVisibility.FamilyOrAssembly:
                // CCI's version of IsVisibleOutsideAssembly doesn't
                // consider protected members as being visible but for
                // our purposes which is to write CS files that can
                // be compiled we always need the protected members
                return(true);
            }

            if (!member.IsVisibleOutsideAssembly())
            {
                // If a type is public, abstract and has a public constructor,
                // then it must expose all abstract members.
                if (member.ContainingTypeDefinition.IsAbstract &&
                    member.IsAbstract() &&
                    member.ContainingTypeDefinition.IsConstructorVisible()
                    )
                {
                    return(true);
                }
                return(false);
            }

            return(true);
        }
Exemple #3
0
        public virtual bool Include(ITypeDefinitionMember member)
        {
            // Include internal and private protected members.
            if (member.Visibility == TypeMemberVisibility.Family ||
                member.Visibility == TypeMemberVisibility.FamilyAndAssembly)
            {
                // Similar to special case in PublicOnlyCciFilter, include protected members even of a sealed type.
                // This is necessary to generate compilable code e.g. callers with IVT dependencies on this assembly
                // may call internal methods in a sealed type. (IsVisibleToFriendAssemblies() includes the IsSealed
                // check for other use cases besides this one.)
                return(true);
            }

            // Include public(-ish) members and explicit interface implementations.
            if (member.IsVisibleToFriendAssemblies())
            {
                return(true);
            }

            // If a type is abstract and has an internal or public constructor, it must expose all abstract members.
            var containingType = member.ContainingTypeDefinition;

            if (containingType.IsAbstract &&
                member.IsAbstract() &&
                containingType.IsConstructorVisibleToFriendAssemblies())
            {
                return(true);
            }

            // Otherwise...
            return(false);
        }
        public override DifferenceType Diff(IDifferences differences, ITypeDefinitionMember impl, ITypeDefinitionMember contract)
        {
            if (impl == null || contract == null)
            {
                return(DifferenceType.Unknown);
            }

            if (impl.IsAbstract() && !contract.IsAbstract())
            {
                differences.AddIncompatibleDifference("CannotMakeMemberAbstract", impl.GetMemberViolationMessage("Member", $"is abstract in the {Implementation}", $"is not abstract in the {Contract}"));
                return(DifferenceType.Changed);
            }

            return(DifferenceType.Unknown);
        }
        public override DifferenceType Diff(IDifferences differences, ITypeDefinitionMember impl, ITypeDefinitionMember contract)
        {
            if (impl == null || contract == null)
                return DifferenceType.Unknown;

            if (impl.IsAbstract() && !contract.IsAbstract())
            {
                differences.AddIncompatibleDifference("CannotMakeMemberAbstract",
                    "Member '{0}' is abstract in the implementation but is not abstract in the contract.",
                    impl.FullName());

                return DifferenceType.Changed;
            }

            return DifferenceType.Unknown;
        }
        public override DifferenceType Diff(IDifferences differences, ITypeDefinitionMember impl, ITypeDefinitionMember contract)
        {
            if (impl == null || contract == null)
            {
                return(DifferenceType.Unknown);
            }

            if (impl.IsAbstract() && !contract.IsAbstract())
            {
                differences.AddIncompatibleDifference("CannotMakeMemberAbstract",
                                                      $"Member '{impl.FullName()}' is abstract in the {Implementation} but is not abstract in the {Contract}.");

                return(DifferenceType.Changed);
            }

            return(DifferenceType.Unknown);
        }