Exemplo n.º 1
0
        private SyntaxNode VisitBasePropertyDeclaration(BasePropertyDeclarationSyntax node)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            var symbol = model.GetDeclaredSymbol(node) as IPropertySymbol;

            var hasPrecondDeclaration  = node.HasAnyPreconditionAttribute(model);
            var hasPostcondDeclaration = node.HasAnyPostconditionAttribute(model);
            var hasContractDeclaration = hasPrecondDeclaration || hasPostcondDeclaration;

            var hasPrecond  = symbol.HasAnyPrecondition(model);
            var hasPostcond = symbol.HasAnyPostcondition(model);
            var hasContract = hasPrecond || hasPostcond;

            var loc = node.GetLocation();

            if (hasContractDeclaration)
            {
                //No contracts on partial members
                if (node.IsPartial())
                {
                    context.Diagnostics.Add(DiagnosticFactory.NoContractsOnPartialMembers(loc));
                }

                //No contracts on extern members
                if (node.IsExtern())
                {
                    context.Diagnostics.Add(DiagnosticFactory.NoContractsOnExternMembers(loc));
                }
            }

            if (hasPrecondDeclaration)
            {
                //No preconditions on inherited members
                if (symbol.IsOverrideOrInterfaceImplementation())
                {
                    context.Diagnostics.Add(DiagnosticFactory.NoPreconditiosnOnInheritedMembers(loc));
                }

                //No preconditions on invalid types
                foreach (var c in symbol.GetPreconditions(model, contractProvider))
                {
                    if (!c.IsValidType(symbol.Type))
                    {
                        context.Diagnostics.Add(DiagnosticFactory.InvalidTypeForContract(c, loc));
                    }
                }
            }

            if (hasPostcondDeclaration)
            {
                //No postconditions on invalid return types
                foreach (var c in symbol.GetPostconditions(model, contractProvider))
                {
                    if (!c.IsValidType(symbol.Type))
                    {
                        context.Diagnostics.Add(DiagnosticFactory.InvalidTypeForContract(c, loc));
                    }
                }
            }

            if (hasPostcond)
            {
                //No postconditions on iterator blocks (must be re-checks on inherited members)
                if (node.IsIteratorBlock())
                {
                    context.Diagnostics.Add(DiagnosticFactory.NoPostconditionsOnIteratorBlocks(loc));
                }
            }

            if (hasPrecond)
            {
                //Members cannot have preconditions from multiple sources
                var precondSourceCount = symbol
                                         .OverriddenAndImplementedInterfaceMembers()
                                         .Count(m => m.GetDeclaredPreconditions(model, contractProvider)
                                                .Any());

                if (precondSourceCount > 1)
                {
                    context.Diagnostics.Add(DiagnosticFactory.MembersCannotInheritPreconditionsFromMultipleSources(loc));
                }
            }

            return(node);
        }