// Copyright (c) Microsoft Corporation. All rights reserved. // using System; using System.Collections.Generic; using System.Xml.XPath; namespace Microsoft.Ddue.Tools { public class CPlusPlusDeclarationSyntaxGenerator : SyntaxGeneratorTemplate { public CPlusPlusDeclarationSyntaxGenerator (XPathNavigator configuration) : base(configuration) { if (String.IsNullOrEmpty(language)) language = "ManagedCPlusPlus"; } // namespace: done public override void WriteNamespaceSyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = reflection.Evaluate(apiNameExpression).ToString(); writer.WriteKeyword("namespace"); writer.WriteString(" "); writer.WriteIdentifier(name); } public override void WriteClassSyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = reflection.Evaluate(apiNameExpression).ToString(); bool isAbstract = (bool) reflection.Evaluate(apiIsAbstractTypeExpression); bool isSealed = (bool) reflection.Evaluate(apiIsSealedTypeExpression); bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression); if (isSerializable) WriteAttribute("T:System.SerializableAttribute", true, writer); WriteAttributes(reflection, writer); WriteGenericTemplates(reflection, writer); WriteVisibility(reflection, writer); writer.WriteString(" "); writer.WriteKeyword("ref class"); writer.WriteString(" "); writer.WriteIdentifier(name); if (isAbstract) { writer.WriteString(" "); writer.WriteKeyword("abstract"); } if (isSealed) { writer.WriteString(" "); writer.WriteKeyword("sealed"); } WriteBaseClassAndImplementedInterfaces(reflection, writer); } // structure: add base type declaration public override void WriteStructureSyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = (string) reflection.Evaluate(apiNameExpression); bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression); if (isSerializable) WriteAttribute("T:System.SerializableAttribute", true, writer); WriteAttributes(reflection, writer); WriteGenericTemplates(reflection, writer); WriteVisibility(reflection, writer); writer.WriteString(" "); writer.WriteKeyword("value class"); writer.WriteString(" "); writer.WriteIdentifier(name); WriteImplementedInterfaces(reflection, writer); } public override void WriteInterfaceSyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = (string) reflection.Evaluate(apiNameExpression); WriteAttributes(reflection, writer); WriteGenericTemplates(reflection, writer); WriteVisibility(reflection, writer); writer.WriteString(" "); writer.WriteKeyword("interface class"); writer.WriteString(" "); writer.WriteIdentifier(name); WriteImplementedInterfaces(reflection, writer); } // delegate: done public override void WriteDelegateSyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = (string) reflection.Evaluate(apiNameExpression); bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression); if (isSerializable) WriteAttribute("T:System.SerializableAttribute", true, writer); WriteAttributes(reflection, writer); WriteGenericTemplates(reflection, writer); WriteVisibility(reflection, writer); writer.WriteString(" "); writer.WriteKeyword("delegate"); writer.WriteString(" "); WriteReturnValue(reflection, writer); writer.WriteString(" "); writer.WriteIdentifier(name); WriteMethodParameters(reflection, writer); } public override void WriteEnumerationSyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = (string) reflection.Evaluate(apiNameExpression); bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression); if (isSerializable) WriteAttribute("T:System.SerializableAttribute", true, writer); WriteAttributes(reflection, writer); WriteVisibility(reflection, writer); writer.WriteString(" "); writer.WriteKeyword("enum class"); writer.WriteString(" "); writer.WriteIdentifier(name); // *** ENUM BASE *** } public override void WriteConstructorSyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = (string) reflection.Evaluate(apiContainingTypeNameExpression); bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression); WriteAttributes(reflection, writer); WriteVisibility(reflection, writer); writer.WriteString(":"); writer.WriteLine(); if (isStatic) { writer.WriteKeyword("static"); writer.WriteString(" "); } writer.WriteIdentifier(name); WriteMethodParameters(reflection, writer); } public override void WriteNormalMethodSyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = (string) reflection.Evaluate(apiNameExpression); string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression); bool isExplicit = (bool) reflection.Evaluate(apiIsExplicitImplementationExpression); WriteAttributes(reflection, writer); if (typeSubgroup == "interface") { WriteGenericTemplates(reflection, writer); WriteReturnValue(reflection, writer); writer.WriteString(" "); writer.WriteIdentifier(name); WriteMethodParameters(reflection, writer); } else { WriteProcedureVisibility(reflection, writer); WriteGenericTemplates(reflection, writer); WritePrefixProcedureModifiers(reflection, writer); WriteReturnValue(reflection, writer); writer.WriteString(" "); writer.WriteIdentifier(name); WriteMethodParameters(reflection, writer); WritePostfixProcedureModifiers(reflection, writer); } WriteExplicitImplementations(reflection, writer); } private void WriteExplicitImplementations (XPathNavigator reflection, SyntaxWriter writer) { bool isExplicit = (bool)reflection.Evaluate(apiIsExplicitImplementationExpression); if (isExplicit) { writer.WriteString(" = "); XPathNodeIterator implements = reflection.Select(apiImplementedMembersExpression); while (implements.MoveNext()) { XPathNavigator implement = implements.Current; //string id = (string)implement.GetAttribute("api", String.Empty); XPathNavigator contract = implement.SelectSingleNode(memberDeclaringTypeExpression); if (implements.CurrentPosition > 1) writer.WriteString(", "); WriteTypeReference(contract, false, writer); writer.WriteString("::"); WriteMemberReference(implement, writer); // writer.WriteReferenceLink(id); } } } public override void WriteOperatorSyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = (string) reflection.Evaluate(apiNameExpression); string identifier; switch (name) { case "UnaryPlus": identifier = "+"; break; case "UnaryNegation": identifier = "-"; break; case "Increment": identifier = "++"; break; case "Decrement": identifier = "--"; break; // unary logical operators case "LogicalNot": identifier = "!"; break; // binary comparison operators case "Equality": identifier = "=="; break; case "Inequality": identifier = "!="; break; case "LessThan": identifier = "<"; break; case "GreaterThan": identifier = ">"; break; case "LessThanOrEqual": identifier = "<="; break; case "GreaterThanOrEqual": identifier = ">="; break; // binary math operators case "Addition": identifier = "+"; break; case "Subtraction": identifier = "-"; break; case "Multiply": identifier = "*"; break; case "Division": identifier = "/"; break; case "Modulus": identifier = "%"; break; // binary logical operators case "BitwiseAnd": identifier = "&"; break; case "BitwiseOr": identifier = "|"; break; case "ExclusiveOr": identifier = "^"; break; // bit-array operators case "OnesComplement": identifier = "~"; break; case "LeftShift": identifier = "<<"; break; case "RightShift": identifier = ">>"; break; // others case "Comma": identifier = ","; break; case "MemberSelection": identifier = "->"; break; case "AddressOf": identifier = "&"; break; case "PointerDereference": identifier = "*"; break; case "Assign": identifier = "="; break; // unrecognized operator default: identifier = null; break; } if (identifier == null) { writer.WriteMessage("UnsupportedOperator_" + Language); } else { WriteProcedureVisibility(reflection, writer); WritePrefixProcedureModifiers(reflection, writer); WriteReturnValue(reflection, writer); writer.WriteString(" "); writer.WriteKeyword("operator"); writer.WriteString(" "); writer.WriteIdentifier(identifier); WriteMethodParameters(reflection, writer); } } public override void WriteCastSyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = (string)reflection.Evaluate(apiNameExpression); WritePrefixProcedureModifiers(reflection, writer); if (name == "Implicit") { writer.WriteKeyword("implicit operator"); } else if (name == "Explicit") { writer.WriteKeyword("explicit operator"); } else { throw new Exception(); } writer.WriteString(" "); WriteReturnValue(reflection, writer); writer.WriteString(" "); WriteMethodParameters(reflection, writer); } public override void WritePropertySyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = (string) reflection.Evaluate(apiNameExpression); string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression); bool isDefault = (bool)reflection.Evaluate(apiIsDefaultMemberExpression); bool hasGetter = (bool) reflection.Evaluate(apiIsReadPropertyExpression); bool hasSetter = (bool) reflection.Evaluate(apiIsWritePropertyExpression); bool isExplicit = (bool) reflection.Evaluate(apiIsExplicitImplementationExpression); XPathNodeIterator parameters = reflection.Select(apiParametersExpression); WriteAttributes(reflection, writer); WriteProcedureVisibility(reflection, writer); WritePrefixProcedureModifiers(reflection, writer); writer.WriteKeyword("property"); writer.WriteString(" "); WriteReturnValue(reflection, writer); writer.WriteString(" "); // if is default member, write default, otherwise write name if (isDefault) { writer.WriteKeyword("default"); } else { writer.WriteIdentifier(name); } if (parameters.Count > 0) { writer.WriteString("["); WriteParameters(parameters.Clone(), false, writer); writer.WriteString("]"); } writer.WriteString(" {"); writer.WriteLine(); if (hasGetter) { writer.WriteString("\t"); WriteReturnValue(reflection, writer); writer.WriteString(" "); writer.WriteKeyword("get"); writer.WriteString(" "); writer.WriteString("("); WriteParameters(parameters.Clone(), false, writer); writer.WriteString(")"); WritePostfixProcedureModifiers(reflection, writer); if (isExplicit) { XPathNavigator implement = reflection.SelectSingleNode(apiImplementedMembersExpression); XPathNavigator contract = implement.SelectSingleNode(memberDeclaringTypeExpression); //string id = (string) implement.GetAttribute("api", String.Empty); writer.WriteString(" = "); WriteTypeReference(contract, false, writer); writer.WriteString("::"); WriteMemberReference(implement, writer); //writer.WriteReferenceLink(id); writer.WriteString("::"); writer.WriteKeyword("get"); } writer.WriteString(";"); writer.WriteLine(); } if (hasSetter) { writer.WriteString("\t"); writer.WriteKeyword("void"); writer.WriteString(" "); writer.WriteKeyword("set"); writer.WriteString(" "); writer.WriteString("("); if (parameters.Count > 0) { WriteParameters(parameters.Clone(), false, writer); writer.WriteString(", "); } WriteReturnValue(reflection, writer); writer.WriteString(" "); writer.WriteParameter("value"); writer.WriteString(")"); WritePostfixProcedureModifiers(reflection, writer); if (isExplicit) { XPathNavigator implement = reflection.SelectSingleNode(apiImplementedMembersExpression); XPathNavigator contract = implement.SelectSingleNode(memberDeclaringTypeExpression); //string id = (string) implement.GetAttribute("api", String.Empty); writer.WriteString(" = "); WriteTypeReference(contract, false, writer); writer.WriteString("::"); WriteMemberReference(implement, writer); //writer.WriteReferenceLink(id); writer.WriteString("::"); writer.WriteKeyword("set"); } writer.WriteString(";"); writer.WriteLine(); } writer.WriteString("}"); } public override void WriteEventSyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = (string) reflection.Evaluate(apiNameExpression); XPathNavigator handler = reflection.SelectSingleNode(apiHandlerOfEventExpression); WriteAttributes(reflection, writer); WriteProcedureVisibility(reflection, writer); WritePrefixProcedureModifiers(reflection, writer); writer.WriteString(" "); writer.WriteKeyword("event"); writer.WriteString(" "); WriteTypeReference(handler, writer); writer.WriteString(" "); writer.WriteIdentifier(name); writer.WriteString(" {"); writer.WriteLine(); writer.WriteString("\t"); writer.WriteKeyword("void"); writer.WriteString(" "); writer.WriteKeyword("add"); writer.WriteString(" ("); WriteTypeReference(handler, writer); writer.WriteString(" "); writer.WriteParameter("value"); writer.WriteString(")"); writer.WriteString(";"); writer.WriteLine(); writer.WriteString("\t"); writer.WriteKeyword("void"); writer.WriteString(" "); writer.WriteKeyword("remove"); writer.WriteString(" ("); WriteTypeReference(handler, writer); writer.WriteString(" "); writer.WriteParameter("value"); writer.WriteString(")"); writer.WriteString(";"); writer.WriteLine(); writer.WriteString("}"); } public override void WriteFieldSyntax (XPathNavigator reflection, SyntaxWriter writer) { string name = (string) reflection.Evaluate(apiNameExpression); bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression); bool isLiteral = (bool) reflection.Evaluate(apiIsLiteralFieldExpression); bool isInitOnly = (bool) reflection.Evaluate(apiIsInitOnlyFieldExpression); bool isSerialized = (bool) reflection.Evaluate(apiIsSerializedFieldExpression); if (!isSerialized) WriteAttribute("T:System.NonSerializedAttribute", true, writer); WriteAttributes(reflection, writer); WriteVisibility(reflection, writer); writer.WriteString(":"); writer.WriteLine(); if (isStatic) { if (isLiteral) { writer.WriteKeyword("literal"); } else { writer.WriteKeyword("static"); } writer.WriteString(" "); } if (isInitOnly) { writer.WriteKeyword("initonly"); writer.WriteString(" "); } WriteReturnValue(reflection, writer); writer.WriteString(" "); writer.WriteIdentifier(name); } private void WritePrefixProcedureModifiers (XPathNavigator reflection, SyntaxWriter writer) { // interface members don't get modified string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression); if (typeSubgroup == "interface") return; bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression); bool isVirtual = (bool) reflection.Evaluate(apiIsVirtualExpression); if (isStatic) { writer.WriteKeyword("static"); writer.WriteString(" "); } else if (isVirtual) { writer.WriteKeyword("virtual"); writer.WriteString(" "); } } private void WritePostfixProcedureModifiers (XPathNavigator reflection, SyntaxWriter writer) { // interface members don't get modified string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression); if (typeSubgroup == "interface") return; bool isVirtual = (bool) reflection.Evaluate(apiIsVirtualExpression); bool isAbstract = (bool) reflection.Evaluate(apiIsAbstractProcedureExpression); bool isFinal = (bool) reflection.Evaluate(apiIsFinalExpression); bool isOverride = (bool) reflection.Evaluate(apiIsOverrideExpression); if (isVirtual) { if (isAbstract) { writer.WriteString(" "); writer.WriteKeyword("abstract"); } if (isOverride) { writer.WriteString(" "); writer.WriteKeyword("override"); } if (isFinal) { writer.WriteString(" "); writer.WriteKeyword("sealed"); } } } // Visibility private void WriteProcedureVisibility (XPathNavigator reflection, SyntaxWriter writer) { string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression); if (typeSubgroup != "interface") { WriteVisibility(reflection, writer); writer.WriteString(":"); writer.WriteLine(); } } private void WriteVisibility (XPathNavigator reflection, SyntaxWriter writer) { string visibility = reflection.Evaluate(apiVisibilityExpression).ToString(); switch (visibility) { case "public": writer.WriteKeyword("public"); break; case "family": writer.WriteKeyword("protected"); break; case "family or assembly": writer.WriteKeyword("protected public"); break; case "family and assembly": writer.WriteKeyword("protected private"); break; case "assembly": writer.WriteKeyword("internal"); break; case "private": writer.WriteKeyword("private"); break; } } // Generics private void WriteGenericTemplates (XPathNavigator reflection, SyntaxWriter writer) { XPathNodeIterator templateNodes = (XPathNodeIterator) reflection.Evaluate(apiTemplatesExpression); if (templateNodes.Count == 0) return; XPathNavigator[] templates = ConvertIteratorToArray(templateNodes); if (templates.Length == 0) return; // generic declaration writer.WriteKeyword("generic"); writer.WriteString("<"); for (int i=0; i 0) writer.WriteString(", "); writer.WriteKeyword("typename"); writer.WriteString(" "); writer.WriteString(name); } writer.WriteString(">"); writer.WriteLine(); // generic constraints foreach (XPathNavigator template in templates) { bool constrained = (bool) template.Evaluate(templateIsConstrainedExpression); if (!constrained) continue; string name = (string) template.Evaluate(templateNameExpression); writer.WriteKeyword("where"); writer.WriteString(" "); writer.WriteString(name); writer.WriteString(" : "); bool value = (bool) template.Evaluate(templateIsValueTypeExpression); bool reference = (bool) template.Evaluate(templateIsReferenceTypeExpression); bool constructor = (bool) template.Evaluate(templateIsConstructableExpression); XPathNodeIterator constraints = template.Select(templateConstraintsExpression); // keep track of whether there is a previous constraint, so we know whether to put a comma bool previous = false; if (value) { if (previous) writer.WriteString(", "); writer.WriteKeyword("value class"); previous = true; } if (reference) { if (previous) writer.WriteString(", "); writer.WriteKeyword("ref class"); previous = true; } if (constructor) { if (previous) writer.WriteString(", "); writer.WriteKeyword("gcnew"); writer.WriteString("()"); previous = true; } foreach (XPathNavigator constraint in constraints) { if (previous) writer.WriteString(", "); WriteTypeReference(constraint, false, writer); previous = true; } writer.WriteLine(); } } // Interfaces private void WriteImplementedInterfaces (XPathNavigator reflection, SyntaxWriter writer) { XPathNodeIterator implements = reflection.Select(apiImplementedInterfacesExpression); if (implements.Count == 0) return; writer.WriteString(" : "); while (implements.MoveNext()) { XPathNavigator implement = implements.Current; WriteTypeReference(implement, false, writer); if (implements.CurrentPosition < implements.Count) { writer.WriteString(", "); if (writer.Position > maxPosition) { writer.WriteLine(); writer.WriteString("\t"); } } } } private void WriteBaseClassAndImplementedInterfaces (XPathNavigator reflection, SyntaxWriter writer) { XPathNavigator baseClass = reflection.SelectSingleNode(apiBaseClassExpression); XPathNodeIterator implements = reflection.Select(apiImplementedInterfacesExpression); bool hasBaseClass = (baseClass != null) && !((bool) baseClass.Evaluate(typeIsObjectExpression)); bool hasImplementedInterfaces = (implements.Count > 0); if (hasBaseClass || hasImplementedInterfaces) { writer.WriteString(" : "); if (hasBaseClass) { writer.WriteKeyword("public"); writer.WriteString(" "); WriteTypeReference(baseClass, false, writer); if (hasImplementedInterfaces) { writer.WriteString(", "); if (writer.Position > maxPosition) { writer.WriteLine(); writer.WriteString("\t"); } } } while (implements.MoveNext()) { XPathNavigator implement = implements.Current; WriteTypeReference(implement, false, writer); if (implements.CurrentPosition < implements.Count) { writer.WriteString(", "); if (writer.Position > maxPosition) { writer.WriteLine(); writer.WriteString("\t"); } } } } } // Return Value private void WriteReturnValue (XPathNavigator reflection, SyntaxWriter writer) { XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression); if (type == null) { writer.WriteKeyword("void"); } else { WriteTypeReference(type, writer); } } private void WriteMethodParameters (XPathNavigator reflection, SyntaxWriter writer) { XPathNodeIterator parameters = reflection.Select(apiParametersExpression); writer.WriteString("("); if (parameters.Count > 0) { writer.WriteLine(); WriteParameters(parameters, true, writer); } writer.WriteString(")"); } private void WriteParameters (XPathNodeIterator parameters, bool multiline, SyntaxWriter writer) { while (parameters.MoveNext()) { XPathNavigator parameter = parameters.Current; XPathNavigator type = parameter.SelectSingleNode(parameterTypeExpression); string name = (string) parameter.Evaluate(parameterNameExpression); bool isIn = (bool) parameter.Evaluate(parameterIsInExpression); bool isOut = (bool) parameter.Evaluate(parameterIsOutExpression); bool isParamArray = (bool) parameter.Evaluate(parameterIsParamArrayExpression); if (multiline) { writer.WriteString("\t"); } if (isIn) { WriteAttribute("T:System.Runtime.InteropServices.InAttribute", false, writer); writer.WriteString(" "); } if (isOut) { WriteAttribute("T:System.Runtime.InteropServices.OutAttribute", false, writer); writer.WriteString(" "); } if (isParamArray) writer.WriteString("... "); WriteTypeReference(type, writer); writer.WriteString(" "); writer.WriteParameter(name); if (parameters.CurrentPosition < parameters.Count) writer.WriteString(", "); if (multiline) writer.WriteLine(); } } // Type references private void WriteTypeReference (XPathNavigator reference, SyntaxWriter writer) { WriteTypeReference(reference, true, writer); } private void WriteTypeReference (XPathNavigator reference, bool handle, SyntaxWriter writer) { switch (reference.LocalName) { case "arrayOf": XPathNavigator element = reference.SelectSingleNode(typeExpression); int rank = Convert.ToInt32( reference.GetAttribute("rank",String.Empty) ); writer.WriteKeyword("array"); writer.WriteString("<"); WriteTypeReference(element, writer); if (rank > 1) { writer.WriteString(","); writer.WriteString(rank.ToString()); } writer.WriteString(">"); if (handle) writer.WriteString("^"); break; case "pointerTo": XPathNavigator pointee = reference.SelectSingleNode(typeExpression); WriteTypeReference(pointee, writer); writer.WriteString("*"); break; case "referenceTo": XPathNavigator referee = reference.SelectSingleNode(typeExpression); WriteTypeReference(referee, writer); writer.WriteString("%"); break; case "type": string id = reference.GetAttribute("api", String.Empty); bool isRef = (reference.GetAttribute("ref", String.Empty) == "true"); WriteNormalTypeReference(id, writer); XPathNodeIterator typeModifiers = reference.Select(typeModifiersExpression); while (typeModifiers.MoveNext()) { WriteTypeReference(typeModifiers.Current, writer); } if (handle && isRef) writer.WriteString("^"); break; case "template": string name = reference.GetAttribute("name", String.Empty); writer.WriteString(name); XPathNodeIterator modifiers = reference.Select(typeModifiersExpression); while (modifiers.MoveNext()) { WriteTypeReference(modifiers.Current, writer); } break; case "specialization": writer.WriteString("<"); XPathNodeIterator arguments = reference.Select(specializationArgumentsExpression); while (arguments.MoveNext()) { if (arguments.CurrentPosition > 1) writer.WriteString(", "); WriteTypeReference(arguments.Current, writer); } writer.WriteString(">"); break; } } private void WriteNormalTypeReference (string reference, SyntaxWriter writer) { switch (reference) { case "T:System.Void": writer.WriteReferenceLink(reference, "void"); break; case "T:System.Boolean": writer.WriteReferenceLink(reference, "bool"); break; case "T:System.Byte": writer.WriteReferenceLink(reference, "unsigned char"); break; case "T:System.SByte": writer.WriteReferenceLink(reference, "signed char"); break; case "T:System.Char": writer.WriteReferenceLink(reference, "wchar_t"); break; case "T:System.Int16": writer.WriteReferenceLink(reference, "short"); break; case "T:System.Int32": writer.WriteReferenceLink(reference, "int"); break; case "T:System.Int64": writer.WriteReferenceLink(reference, "long long"); break; case "T:System.UInt16": writer.WriteReferenceLink(reference, "unsigned short"); break; case "T:System.UInt32": writer.WriteReferenceLink(reference, "unsigned int"); break; case "T:System.UInt64": writer.WriteReferenceLink(reference, "unsigned long long"); break; case "T:System.Single": writer.WriteReferenceLink(reference, "float"); break; case "T:System.Double": writer.WriteReferenceLink(reference, "double"); break; default: writer.WriteReferenceLink(reference); break; } } // Attributes private void WriteAttribute (string reference, bool newline, SyntaxWriter writer) { writer.WriteString("["); writer.WriteReferenceLink(reference); writer.WriteString("]"); if (newline) writer.WriteLine(); } private void WriteAttributes (XPathNavigator reflection, SyntaxWriter writer) { XPathNodeIterator attributes = (XPathNodeIterator) reflection.Evaluate(apiAttributesExpression); foreach (XPathNavigator attribute in attributes) { XPathNavigator type = attribute.SelectSingleNode(typeExpression); writer.WriteString("["); WriteTypeReference(type, false, writer); XPathNodeIterator arguments = (XPathNodeIterator) attribute.Select(attributeArgumentsExpression); XPathNodeIterator assignments = (XPathNodeIterator) attribute.Select(attributeAssignmentsExpression); if ((arguments.Count > 0) || (assignments.Count > 0)) { writer.WriteString("("); while (arguments.MoveNext()) { XPathNavigator argument = arguments.Current; if (arguments.CurrentPosition > 1) { writer.WriteString(", "); if (writer.Position > maxPosition) { writer.WriteLine(); writer.WriteString("\t"); } } WriteValue(argument, writer); } if ((arguments.Count > 0) && (assignments.Count > 0)) writer.WriteString(", "); while (assignments.MoveNext()) { XPathNavigator assignment = assignments.Current; if (assignments.CurrentPosition > 1) { writer.WriteString(", "); if (writer.Position > maxPosition) { writer.WriteLine(); writer.WriteString("\t"); } } writer.WriteString((string) assignment.Evaluate(assignmentNameExpression)); writer.WriteString(" = "); WriteValue(assignment, writer); } writer.WriteString(")"); } writer.WriteString("]"); writer.WriteLine(); } } private void WriteValue (XPathNavigator parent, SyntaxWriter writer) { XPathNavigator type = parent.SelectSingleNode(attributeTypeExpression); XPathNavigator value = parent.SelectSingleNode(valueExpression); if (value == null) Console.WriteLine("null value"); switch (value.LocalName) { case "nullValue": writer.WriteKeyword("nullptr"); break; case "typeValue": writer.WriteKeyword("typeof"); writer.WriteString("("); WriteTypeReference(value.SelectSingleNode(typeExpression), false, writer); writer.WriteString(")"); break; case "enumValue": XPathNodeIterator fields = value.SelectChildren(XPathNodeType.Element); while (fields.MoveNext()) { string name = fields.Current.GetAttribute("name", String.Empty); if (fields.CurrentPosition > 1) writer.WriteString("|"); WriteTypeReference(type, writer); writer.WriteString("::"); writer.WriteString(name); } break; case "value": string text = value.Value; string typeId = type.GetAttribute("api", String.Empty); switch (typeId) { case "T:System.String": writer.WriteString("L\""); writer.WriteString(text); writer.WriteString("\""); break; case "T:System.Boolean": bool bool_value = Convert.ToBoolean(text); if (bool_value) { writer.WriteKeyword("true"); } else { writer.WriteKeyword("false"); } break; case "T:System.Char": writer.WriteString(@"L'"); writer.WriteString(text); writer.WriteString(@"'"); break; } break; } } private void WriteMemberReference (XPathNavigator member, SyntaxWriter writer) { string api = member.GetAttribute("api", String.Empty); writer.WriteReferenceLink(api); } private static XPathNavigator[] ConvertIteratorToArray (XPathNodeIterator iterator) { XPathNavigator[] result = new XPathNavigator[iterator.Count]; for (int i=0; i