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); }
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 })); }