in src/dotnet-svcutil/lib/src/FrameworkFork/Microsoft.Xml/Xml/schema/GenerateConverter.cs [371:662]
public void Generate()
{
AutoGenWriter autoGenWriter;
//-----------------------------------------------
// XmlBaseConverter
//-----------------------------------------------
// Output list of all CLR types used by the generated code
autoGenWriter = new AutoGenWriter("XmlValueConverter.cs", "AUTOGENERATED_XMLBASECONVERTER");
_w = autoGenWriter.OpenIndented();
List<Type> uniqueTypes = new List<Type>();
foreach (ConversionRuleGroup group in ConversionsRules)
{
foreach (Type tSrc in group.FindUniqueSourceTypes(null))
if (!uniqueTypes.Contains(tSrc)) uniqueTypes.Add(tSrc);
foreach (Type tDst in group.FindUniqueDestinationTypes(null))
if (!uniqueTypes.Contains(tDst)) uniqueTypes.Add(tDst);
}
foreach (Type t in uniqueTypes)
_w.WriteLine("protected static readonly Type " + ClrTypeName(t) + "Type = typeof(" + ClrTypeToCSharpName(t) + ");");
_w.WriteLine();
// Output default methods which call ChangeType
foreach (Type tDst in InterfaceTypes)
{
foreach (Type tSrc in InterfaceTypes)
{
if (tDst == typeof(object) && tSrc == typeof(object))
continue;
StartMethodSignature(tSrc, tDst);
_w.Write("return (" + ClrTypeToCSharpName(tDst) + ") ChangeType((object) value, ");
if (tDst == typeof(object))
_w.Write("destinationType");
else
_w.Write(ClrTypeName(tDst) + "Type");
_w.WriteLine(", " + (MethodHasResolver(tSrc, tDst) ? "nsResolver" : "null") + "); }");
}
if (tDst == typeof(string))
{
_w.WriteLine("public override string ToString(string value) {return this.ToString(value, null); }");
_w.WriteLine("public override string ToString(object value) {return this.ToString(value, null); }");
}
if (tDst == typeof(object))
{
_w.WriteLine("public override object ChangeType(string value, Type destinationType) {return this.ChangeType(value, destinationType, null); }");
_w.WriteLine("public override object ChangeType(object value, Type destinationType) {return this.ChangeType(value, destinationType, null); }");
}
_w.WriteLine();
}
autoGenWriter.Close();
//-----------------------------------------------
// Other Converters
//-----------------------------------------------
foreach (ConversionRuleGroup group in ConversionsRules)
{
IList<Type> uniqueSourceTypes, uniqueDestTypes;
autoGenWriter = new AutoGenWriter("XmlValueConverter.cs", "AUTOGENERATED_" + group.Name.ToUpper());
_w = autoGenWriter.OpenIndented();
foreach (Type tDst in InterfaceTypes)
{
// Handle ChangeType methods later
if (tDst == typeof(object))
continue;
_w.WriteLine();
_w.WriteLine("//-----------------------------------------------");
_w.WriteLine("// To" + ClrTypeName(tDst));
_w.WriteLine("//-----------------------------------------------");
_w.WriteLine();
// Create strongly-typed ToXXX methods
foreach (Type tSrc in InterfaceTypes)
{
// Handle ToXXX(object value) method later
if (tSrc == typeof(object))
continue;
IList<ConversionRule> rules = group.Find(XmlTypeCode.None, tSrc, tDst);
if (rules.Count > 0)
{
ConversionRule defaultRule = FindDefaultRule(rules);
if (defaultRule == null)
throw new Exception("If conversion from " + tSrc.Name + " to " + tDst.Name + " exists, a default conversion should also be defined.");
// ToXXX(T value)
StartMethod(tSrc, tDst);
GenerateConversions(defaultRule, rules);
EndMethod();
}
}
// Gather all unique source types which have destination type "tDst"
uniqueSourceTypes = group.FindUniqueSourceTypes(tDst);
if (uniqueSourceTypes.Count > 0)
{
// ToXXX(object value);
StartMethod(typeof(object), tDst);
_w.WriteLine("Type sourceType = value.GetType();");
_w.WriteLine();
foreach (Type tSrc in uniqueSourceTypes)
GenerateConversionsTo(group.Find(XmlTypeCode.None, tSrc, tDst));
// If wildcard destination conversions exist, then delegate to ChangeTypeWildcardDestination method to handle them
_w.WriteLine();
_w.Write("return (" + ClrTypeToCSharpName(tDst) + ") ");
_w.Write(group.FindUniqueSourceTypes(typeof(object)).Count > 0 ? "ChangeTypeWildcardDestination" : "ChangeListType");
_w.WriteLine("(value, " + ClrTypeName(tDst) + "Type, " + (MethodHasResolver(typeof(object), tDst) ? "nsResolver);" : "null);"));
EndMethod();
}
else
{
_w.WriteLine("// This converter does not support conversions to " + ClrTypeName(tDst) + ".");
}
_w.WriteLine();
}
_w.WriteLine();
_w.WriteLine("//-----------------------------------------------");
_w.WriteLine("// ChangeType");
_w.WriteLine("//-----------------------------------------------");
_w.WriteLine();
foreach (Type tSrc in InterfaceTypes)
{
// Handle ChangeType(object) later
if (tSrc == typeof(object))
continue;
// Gather all unique destination types which have source type "tSrc"
uniqueDestTypes = group.FindUniqueDestinationTypes(tSrc);
if (uniqueDestTypes.Count > 0)
{
// ChangeType(T value, Type destinationType);
StartMethod(tSrc, typeof(object));
_w.WriteLine("if (destinationType == ObjectType) destinationType = DefaultClrType;");
foreach (Type tDst in uniqueDestTypes)
GenerateConversionsFrom(group.Find(XmlTypeCode.None, tSrc, tDst));
// If wildcard source conversions exist, then delegate to ChangeTypeWildcardSource method to handle them
_w.WriteLine();
if (group.FindUniqueDestinationTypes(typeof(object)).Count > 0)
_w.Write("return ChangeTypeWildcardSource(value, destinationType, ");
else
_w.Write("return ChangeListType(value, destinationType, ");
_w.WriteLine(MethodHasResolver(typeof(object), tSrc) ? "nsResolver);" : "null);");
EndMethod();
_w.WriteLine();
}
}
// object ChangeType(object value, Type destinationType, IXmlNamespaceResolver resolver);
StartMethod(typeof(object), typeof(object));
_w.WriteLine("Type sourceType = value.GetType();");
_w.WriteLine();
// Generate conversions to destinationType
_w.WriteLine("if (destinationType == ObjectType) destinationType = DefaultClrType;");
// Strongly-typed destinations
foreach (Type tDst in group.FindUniqueDestinationTypes(null))
{
// Only output conversions if the destination is not a wildcard
if (tDst == typeof(object))
continue;
// Get source types that can be converted to the destination type
uniqueSourceTypes = group.FindUniqueSourceTypes(tDst);
// Remove wildcard source rules, as they are handled later
int i = 0;
while (i < uniqueSourceTypes.Count)
{
if (uniqueSourceTypes[i] == typeof(object))
uniqueSourceTypes.RemoveAt(i);
else
i++;
}
if (uniqueSourceTypes.Count != 0)
{
if (IsInterfaceMethod(tDst) && uniqueSourceTypes.Count > 1)
{
_w.Write("if (destinationType == " + ClrTypeName(tDst) + "Type) ");
_w.WriteLine("return this.To" + ClrTypeName(tDst) + "(value" + (MethodHasResolver(tDst, tDst) ? ", nsResolver);" : ");"));
}
else
{
_w.WriteLine("if (destinationType == " + ClrTypeName(tDst) + "Type) {");
_w.Indent++;
foreach (Type tSrc in uniqueSourceTypes)
{
GenerateConversionsTo(group.Find(XmlTypeCode.None, tSrc, tDst));
}
_w.Indent--;
_w.WriteLine("}");
}
}
}
// Generate conversions from wildcard source types
foreach (Type tDst in group.FindUniqueDestinationTypes(typeof(object)))
GenerateConversionsFrom(group.Find(XmlTypeCode.None, typeof(object), tDst));
// Generate conversions to wildcard destination types
foreach (Type tSrc in group.FindUniqueSourceTypes(typeof(object)))
GenerateConversionsTo(group.Find(XmlTypeCode.None, tSrc, typeof(object)));
_w.WriteLine();
_w.WriteLine("return ChangeListType(value, destinationType, nsResolver);");
EndMethod();
uniqueSourceTypes = group.FindUniqueSourceTypes(typeof(object));
uniqueDestTypes = group.FindUniqueDestinationTypes(typeof(object));
if (uniqueSourceTypes.Count != 0 || uniqueDestTypes.Count != 0)
{
_w.WriteLine();
_w.WriteLine();
_w.WriteLine("//-----------------------------------------------");
_w.WriteLine("// Helpers");
_w.WriteLine("//-----------------------------------------------");
_w.WriteLine();
// Generate ChangeTypeWildcardDestination method, which performs conversions that are the same no matter what the destination type is
if (uniqueSourceTypes.Count != 0)
{
_w.WriteLine("private object ChangeTypeWildcardDestination(object value, Type destinationType, IXmlNamespaceResolver nsResolver) {");
_w.Indent++;
_w.WriteLine("Type sourceType = value.GetType();");
_w.WriteLine();
foreach (Type tSrc in uniqueSourceTypes)
GenerateConversionsTo(group.Find(XmlTypeCode.None, tSrc, typeof(object)));
_w.WriteLine();
_w.WriteLine("return ChangeListType(value, destinationType, nsResolver);");
_w.Indent--;
_w.WriteLine("}");
}
// Generate ChangeTypeWildcardSource method, which performs conversions that are the same no matter what the source type is
if (uniqueDestTypes.Count != 0)
{
_w.WriteLine("private object ChangeTypeWildcardSource(object value, Type destinationType, IXmlNamespaceResolver nsResolver) {");
_w.Indent++;
foreach (Type tDst in uniqueDestTypes)
GenerateConversionsFrom(group.Find(XmlTypeCode.None, typeof(object), tDst));
_w.WriteLine();
_w.WriteLine("return ChangeListType(value, destinationType, nsResolver);");
_w.Indent--;
_w.WriteLine("}");
}
}
autoGenWriter.Close();
}
}