internal string GenerateSimpleType(
            XmlSchemaSimpleType type,
            CodeCompileUnit compileUnit,
            CodeNamespace mainNamespace,
            CodeGenerationOptions options,
            CodeDomProvider codeProvider)
        {
            CodeTypeDeclaration codeClass = CodeDomHelper.CreateClassDeclaration(type);

            mainNamespace.Types.Add(codeClass);

            CodeDomHelper.GenerateXmlTypeAttribute(codeClass, type.QualifiedName.Name, type.QualifiedName.Namespace);

            XmlSchemaSimpleTypeRestriction restriction = type.Content as XmlSchemaSimpleTypeRestriction;

            Type            baseType = XsdToClrPrimitive(restriction.BaseTypeName);
            CodeMemberField field    = CodeDomHelper.AddField(codeClass, "value", baseType);

            CodeMemberProperty prop = CodeDomHelper.AddPropertyDeclaration(codeClass, field, "Value", baseType);

            CodeDomHelper.AddTextAttribute(prop.CustomAttributes);

            CodeDomHelper.AddCtor(codeClass);
            CodeDomHelper.AddCtor(codeClass, prop);

            // for each facet we support, add validation to the setter
            foreach (object facet in restriction.Facets)
            {
                XmlSchemaLengthFacet length = facet as XmlSchemaLengthFacet;
                if (length != null)
                {
                    int?value = ToInt32(length.Value);
                    if (value.HasValue)
                    {
                        CodeExpression valueLength             = CodeDomHelper.Property(CodeDomHelper.Value(), "Length");
                        CodeBinaryOperatorExpression condition = new CodeBinaryOperatorExpression(valueLength, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(value));
                        prop.SetStatements.Add(new CodeConditionStatement(condition, new CodeStatement[] { CodeDomHelper.ThrowFacetViolation("length", value) }, new CodeStatement[0]));
                    }
                    continue;
                }

                XmlSchemaPatternFacet pattern = facet as XmlSchemaPatternFacet;
                if (pattern != null)
                {
                    // TODO: might want ot validate the pattern value here to make sure that it is a valid Regex.
                    if (!string.IsNullOrEmpty(pattern.Value))
                    {
                        CodeExpression patternMatch =
                            CodeDomHelper.MethodCall(
                                CodeDomHelper.TypeExpr(typeof(Regex)), "IsMatch", new CodeExpression[] { CodeDomHelper.Value(), CodeDomHelper.Primitive(pattern.Value) });

                        CodeBinaryOperatorExpression condition = new CodeBinaryOperatorExpression(patternMatch, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(true));
                        prop.SetStatements.Add(new CodeConditionStatement(condition, new CodeStatement[] { CodeDomHelper.ThrowFacetViolation("pattern", pattern.Value) }, new CodeStatement[0]));
                    }
                    continue;
                }

                XmlSchemaMinLengthFacet minLength = facet as XmlSchemaMinLengthFacet;
                if (minLength != null)
                {
                    int?value = ToInt32(minLength.Value);
                    if (value.HasValue)
                    {
                        CodeExpression valueLength             = CodeDomHelper.Property(CodeDomHelper.Value(), "Length");
                        CodeBinaryOperatorExpression condition = new CodeBinaryOperatorExpression(valueLength, CodeBinaryOperatorType.LessThan, new CodePrimitiveExpression(value));
                        prop.SetStatements.Add(new CodeConditionStatement(condition, new CodeStatement[] { CodeDomHelper.ThrowFacetViolation("minLength", value) }, new CodeStatement[0]));
                    }
                    continue;
                }

                XmlSchemaMaxLengthFacet maxLength = facet as XmlSchemaMaxLengthFacet;
                if (maxLength != null)
                {
                    int?value = ToInt32(maxLength.Value);
                    if (value.HasValue)
                    {
                        CodeExpression valueLength             = CodeDomHelper.Property(CodeDomHelper.Value(), "Length");
                        CodeBinaryOperatorExpression condition = new CodeBinaryOperatorExpression(valueLength, CodeBinaryOperatorType.GreaterThan, new CodePrimitiveExpression(value));
                        prop.SetStatements.Add(new CodeConditionStatement(condition, new CodeStatement[] { CodeDomHelper.ThrowFacetViolation("maxLength", value) }, new CodeStatement[0]));
                    }
                    continue;
                }
            }

            //add ToSrting() Overload and implicit and explicit Cast operators for compatibilty woth previously generated code

            CodeMemberMethod toString = CodeDomHelper.MethodDecl(typeof(string), "ToString", MemberAttributes.Public | MemberAttributes.Override);

            toString.Statements.Add(CodeDomHelper.Return(CodeDomHelper.Property("value")));
            codeClass.Members.Add(toString);

            // Unfortunately CodeDom does not support operators, so we have to use CodeSnippet to generate the Cast operators
            // CodeSnippet is not language aware, so we have to use different snippets for different providers
            // this version only support c# syntax
            if (codeProvider is Microsoft.CSharp.CSharpCodeProvider)
            {
                string implicitCast = string.Format("    public static implicit operator {0}({1} x) {{ return new {0}(x); }}", codeClass.Name, baseType.FullName);
                CodeSnippetTypeMember implicitOp = new CodeSnippetTypeMember(implicitCast);
                codeClass.Members.Add(implicitOp);

                string explicitCast = string.Format("    public static explicit operator {1}({0} x) {{ return x.Value; }}", codeClass.Name, baseType.FullName);
                CodeSnippetTypeMember explicitOp = new CodeSnippetTypeMember(explicitCast);
                codeClass.Members.Add(explicitOp);
            }

            return(codeClass.Name);
        }
예제 #2
0
        internal static CodeStatement ThrowFacetViolation(string facet, object value)
        {
            //"Cannot set value to '{0}'. Constraining facet violation: {1}='{3}'.";
            // generate string.Format call
            string         exception = string.Format("Cannot set value to '{{0}}'. Constraining facet violation: {0}='{1}'.", facet, value);
            CodeExpression format    = MethodCall(TypeExpr(typeof(string)), "Format", new CodeExpression[] { Primitive(exception), CodeDomHelper.Value() });

            return(Throw(typeof(ArgumentException), new CodeExpression[] { format }));
        }