Example #1
0
        public override AstNode Visit(PropertyDefinition node)
        {
            // Get the name expression.
            Expression nameExpression = node.GetNameExpression();

            if (nameExpression == null)
            {
                return(node);
            }

            // Visit the name expression.
            nameExpression.SetHints(Expression.MemberHint);
            nameExpression.Accept(this);

            // Try to cast into a property.
            PropertyVariable   contractProperty;
            DirectPropertySlot directProp = nameExpression.GetNodeValue() as DirectPropertySlot;

            if (directProp != null)
            {
                contractProperty = directProp.Property;
            }
            else
            {
                contractProperty = nameExpression.GetNodeValue() as PropertyVariable;
            }

            // It must be a property reference.
            if (contractProperty == null)
            {
                Error(nameExpression, "expected property reference.");
            }

            // Compare the property types.
            PropertyVariable property = node.GetProperty();

            if (property.GetVariableType() != contractProperty.GetVariableType())
            {
                Error(nameExpression, "contracted property type mismatch.");
            }

            // Instance the get accessor.
            if (contractProperty.GetAccessor != null)
            {
                if (property.GetAccessor == null)
                {
                    Error(nameExpression, "property implementation doesn't have a get accessor.");
                }

                // Both accessors must be methods.
                if (!contractProperty.GetAccessor.IsMethod() || !property.GetAccessor.IsMethod())
                {
                    Error(nameExpression, "property get accessor is not a static method.");
                }

                // The accessors must match.
                if (!MatchFunction(contractProperty.GetAccessor.GetFunctionType(),
                                   property.GetAccessor.GetFunctionType(), 1))
                {
                    Error(nameExpression, "get accessors have mismatching signatures.");
                }

                // Bind the contract.
                Method impl = (Method)property.GetAccessor;
                impl.SetExplicitContract(contractProperty.GetAccessor);
            }
            else if (property.GetAccessor != null)
            {
                Error(nameExpression, "property explicit contract doesn't have a get accessor.");
            }

            // Instance the set accessor.
            if (contractProperty.SetAccessor != null)
            {
                if (property.SetAccessor == null)
                {
                    Error(nameExpression, "property implementation doesn't have a set accessor.");
                }

                // Both accessors must be methods.
                if (!contractProperty.SetAccessor.IsMethod() || !property.SetAccessor.IsMethod())
                {
                    Error(nameExpression, "property set accessor is not a static method.");
                }

                // The accessors must match.
                if (!MatchFunction(contractProperty.SetAccessor.GetFunctionType(),
                                   property.SetAccessor.GetFunctionType(), 1))
                {
                    Error(nameExpression, "set accessors have mismatching signatures.");
                }

                // Bind the contract.
                Method impl = (Method)property.SetAccessor;
                impl.SetExplicitContract(contractProperty.SetAccessor);
            }
            else if (property.SetAccessor != null)
            {
                Error(nameExpression, "property explicit contract doesn't have a set accessor.");
            }

            return(node);
        }