summaryrefslogtreecommitdiffstats
path: root/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/FSharpDeclarationSyntax.cs
diff options
context:
space:
mode:
Diffstat (limited to 'tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/FSharpDeclarationSyntax.cs')
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/FSharpDeclarationSyntax.cs988
1 files changed, 988 insertions, 0 deletions
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/FSharpDeclarationSyntax.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/FSharpDeclarationSyntax.cs
new file mode 100644
index 0000000..7f10807
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/FSharpDeclarationSyntax.cs
@@ -0,0 +1,988 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml.XPath;
+
+
+namespace Microsoft.Ddue.Tools
+{
+
+ public class FSharpDeclarationSyntaxGenerator : SyntaxGeneratorTemplate
+ {
+
+ public FSharpDeclarationSyntaxGenerator(XPathNavigator configuration)
+ : base(configuration)
+ {
+ if (String.IsNullOrEmpty(Language)) Language = "FSharp";
+ }
+
+ // 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)
+ {
+
+ WriteDotNetObject(reflection, writer, "class");
+ }
+
+ // TODO: Use apiContainingTypeSubgroupExpression instead of passing in class, struct, interface
+ public override void WriteStructureSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ WriteDotNetObject(reflection, writer, "struct");
+ }
+
+ public override void WriteInterfaceSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ WriteDotNetObject(reflection, writer, "interface");
+ }
+
+
+ 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", writer);
+
+ WriteAttributes(reflection, writer);
+
+ writer.WriteKeyword("type");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ writer.WriteString(" = ");
+ writer.WriteLine();
+ writer.WriteString(" ");
+ writer.WriteKeyword("delegate");
+ writer.WriteString(" ");
+ writer.WriteKeyword("of");
+ writer.WriteString(" ");
+
+ WriteParameters(reflection, writer);
+
+ writer.WriteKeyword("->");
+ writer.WriteString(" ");
+ WriteReturnValue(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", writer);
+ WriteAttributes(reflection, writer);
+ writer.WriteKeyword("type");
+ writer.WriteString(" ");
+ WriteVisibility(reflection, writer);
+ writer.WriteIdentifier(name);
+ }
+
+ public override void WriteConstructorSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ string name = (string)reflection.Evaluate(apiContainingTypeNameExpression);
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+
+ WriteAttributes(reflection, writer);
+
+ writer.WriteKeyword("new");
+ writer.WriteString(" : ");
+ WriteParameters(reflection, writer);
+ writer.WriteKeyword("->");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+
+ }
+
+ public override void WriteNormalMethodSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isOverride = (bool)reflection.Evaluate(apiIsOverrideExpression);
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isVirtual = (bool)reflection.Evaluate(apiIsVirtualExpression) && !(bool)reflection.Evaluate(apiIsAbstractProcedureExpression);
+ int iterations = isVirtual ? 2 : 1;
+
+ for (int i = 0; i < iterations; i++)
+ {
+
+ WriteAttributes(reflection, writer);
+
+ WriteVisibility(reflection, writer);
+
+ if (isStatic)
+ {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ }
+
+ if (isVirtual)
+ if (i == 0)
+ {
+ writer.WriteKeyword("abstract");
+ writer.WriteString(" ");
+ }
+ else
+ {
+ writer.WriteKeyword("override");
+ writer.WriteString(" ");
+ }
+ else
+ {
+ WriteMemberKeyword(reflection, writer);
+ }
+
+ writer.WriteIdentifier(name);
+ writer.WriteString(" : ");
+ WriteParameters(reflection, writer);
+ writer.WriteKeyword("->");
+ writer.WriteString(" ");
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ WriteGenericTemplateConstraints(reflection, writer);
+
+ if (i == 0)
+ writer.WriteLine();
+ }
+ }
+
+ public override void WriteOperatorSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ string identifier;
+
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+
+ switch (name)
+ {
+ // unary math operators
+ case "UnaryPlus":
+ identifier = "+";
+ break;
+ case "UnaryNegation":
+ identifier = "-";
+ break;
+ case "Increment":
+ identifier = "++";
+ break;
+ case "Decrement":
+ identifier = "--";
+ break;
+ // unary logical operators
+ case "LogicalNot":
+ identifier = "not";
+ break;
+ case "True":
+ identifier = "true";
+ break;
+ case "False":
+ identifier = "false";
+ 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 = null; // No F# equiv.
+ break;
+ case "LeftShift":
+ identifier = "<<<";
+ break;
+ case "RightShift":
+ identifier = ">>>";
+ break;
+ // unrecognized operator
+ default:
+ identifier = null;
+ break;
+ }
+ if (identifier == null)
+ {
+ writer.WriteMessage("UnsupportedOperator_" + Language);
+ }
+ else
+ {
+ if (isStatic)
+ {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ }
+
+ writer.WriteKeyword("let");
+ writer.WriteString(" ");
+ writer.WriteKeyword("inline");
+ writer.WriteKeyword(" ");
+
+ writer.WriteString("(");
+ writer.WriteIdentifier(identifier);
+ writer.WriteString(")");
+
+ WriteParameters(reflection, writer);
+ writer.WriteString(" : ");
+ WriteReturnValue(reflection, writer);
+
+ }
+ }
+
+ public override void WriteCastSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ writer.WriteMessage("UnsupportedCast_" + Language);
+ }
+
+ // DONE
+ public override void WritePropertySyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isGettable = (bool)reflection.Evaluate(apiIsReadPropertyExpression);
+ bool isSettable = (bool)reflection.Evaluate(apiIsWritePropertyExpression);
+
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isVirtual = (bool)reflection.Evaluate(apiIsVirtualExpression) && !(bool)reflection.Evaluate(apiIsAbstractProcedureExpression);
+ int iterations = isVirtual ? 2 : 1;
+
+ for (int i = 0; i < iterations; i++)
+ {
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+
+ if (isStatic)
+ {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ }
+
+ if (isVirtual)
+ if (i == 0)
+ {
+ writer.WriteKeyword("abstract");
+ writer.WriteString(" ");
+ }
+ else
+ {
+ writer.WriteKeyword("override");
+ writer.WriteString(" ");
+ }
+ else
+ {
+ WriteMemberKeyword(reflection, writer);
+ }
+
+ writer.WriteIdentifier(name);
+ writer.WriteString(" : ");
+ WriteReturnValue(reflection, writer);
+
+ if (isSettable)
+ {
+ writer.WriteString(" ");
+ writer.WriteKeyword("with");
+ writer.WriteString(" ");
+
+ string getVisibility = (string)reflection.Evaluate(apiGetVisibilityExpression);
+ if (!String.IsNullOrEmpty(getVisibility))
+ {
+ WriteVisibility(getVisibility, writer);
+ }
+
+ writer.WriteKeyword("get");
+ writer.WriteString(", ");
+
+ string setVisibility = (string)reflection.Evaluate(apiSetVisibilityExpression);
+ if (!String.IsNullOrEmpty(setVisibility))
+ {
+ WriteVisibility(setVisibility, writer);
+ }
+
+ writer.WriteKeyword("set");
+ }
+ if (i == 0)
+ writer.WriteLine();
+ }
+ }
+
+ public override void WriteEventSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ XPathNavigator handler = reflection.SelectSingleNode(apiHandlerOfEventExpression);
+ XPathNavigator args = reflection.SelectSingleNode(apiEventArgsExpression);
+ bool isVirtual = (bool)reflection.Evaluate(apiIsVirtualExpression) && !(bool)reflection.Evaluate(apiIsAbstractProcedureExpression);
+ int iterations = isVirtual ? 2 : 1;
+
+ for (int i = 0; i < iterations; i++)
+ {
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ if (isVirtual)
+ if (i == 0)
+ {
+ writer.WriteKeyword("abstract");
+ writer.WriteString(" ");
+ }
+ else
+ {
+ writer.WriteKeyword("override");
+ writer.WriteString(" ");
+ }
+ else
+ {
+ WriteMemberKeyword(reflection, writer);
+ }
+ writer.WriteIdentifier(name);
+ writer.WriteString(" : ");
+ writer.WriteReferenceLink("T:Microsoft.FSharp.Control.IEvent");
+
+ writer.WriteString("<");
+ WriteTypeReference(handler, writer);
+ writer.WriteString(",");
+ writer.WriteLine();
+ writer.WriteString(" ");
+ if (args == null)
+ {
+ writer.WriteReferenceLink("T:System.EventArgs");
+ }
+ else
+ {
+ WriteTypeReference(args, writer);
+ }
+ writer.WriteString(">");
+ if (i == 0)
+ writer.WriteLine();
+ }
+ }
+
+
+ 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", writer);
+ WriteAttributes(reflection, writer);
+
+
+ if (isStatic)
+ {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("val");
+ writer.WriteString(" ");
+
+ if (!isInitOnly)
+ {
+ writer.WriteKeyword("mutable");
+ writer.WriteString(" ");
+ }
+
+ WriteVisibility(reflection, writer);
+
+ writer.WriteIdentifier(name);
+
+ writer.WriteString(": ");
+ WriteReturnValue(reflection, writer);
+
+ }
+
+
+ private void WriteDotNetObject(XPathNavigator reflection, SyntaxWriter writer,
+ string kind)
+ {
+ string name = reflection.Evaluate(apiNameExpression).ToString();
+ bool isSerializable = (bool)reflection.Evaluate(apiIsSerializableTypeExpression);
+ XPathNodeIterator implements = reflection.Select(apiImplementedInterfacesExpression);
+ XPathNavigator baseClass = reflection.SelectSingleNode(apiBaseClassExpression);
+ bool hasBaseClass = (baseClass != null) && !((bool)baseClass.Evaluate(typeIsObjectExpression));
+
+ // CLR considers interfaces abstract.
+ bool isAbstract = (bool)reflection.Evaluate(apiIsAbstractTypeExpression) && kind != "interface";
+ bool isSealed = (bool)reflection.Evaluate(apiIsSealedTypeExpression);
+
+ if (isAbstract)
+ WriteAttribute("T:Microsoft.FSharp.Core.AbstractClassAttribute", writer);
+ if (isSealed)
+ WriteAttribute("T:Microsoft.FSharp.Core.SealedAttribute", writer);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+
+ writer.WriteKeyword("type");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteGenericTemplates(reflection, writer);
+ writer.WriteString(" = ");
+
+ if (hasBaseClass || implements.Count != 0)
+ {
+ writer.WriteLine();
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword(kind);
+
+ if (hasBaseClass || implements.Count != 0)
+ {
+ writer.WriteLine();
+ }
+
+ if (hasBaseClass)
+ {
+ writer.WriteString(" ");
+ writer.WriteKeyword("inherit");
+ writer.WriteString(" ");
+ WriteTypeReference(baseClass, writer);
+ writer.WriteLine();
+ }
+
+
+ while (implements.MoveNext())
+ {
+ XPathNavigator implement = implements.Current;
+ writer.WriteString(" ");
+ writer.WriteKeyword("interface");
+ writer.WriteString(" ");
+ WriteTypeReference(implement, writer);
+ writer.WriteLine();
+ }
+
+ if (hasBaseClass || implements.Count != 0)
+ {
+ writer.WriteString(" ");
+ }
+ else
+ {
+ writer.WriteString(" ");
+ }
+
+ writer.WriteKeyword("end");
+
+ }
+
+ // Visibility
+
+ private void WriteVisibility(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ string visibility = reflection.Evaluate(apiVisibilityExpression).ToString();
+ WriteVisibility(visibility, writer);
+ }
+
+
+ private Dictionary<string, string> visibilityDictionary = new Dictionary<string, string>()
+ {
+ { "public", null }, // Default in F#, so unnecessary.
+ { "family", null }, // Not supported in F#, section 8.8 in F# spec.
+ { "family or assembly", null }, // Not supported in F#, section 8.8 in F# spec.
+ { "family and assembly", null }, // Not supported in F#, section 8.8 in F# spec.
+ { "assembly", "internal" },
+ { "private", "private" },
+ };
+
+ // DONE
+ private void WriteVisibility(string visibility, SyntaxWriter writer)
+ {
+
+ if(visibilityDictionary.ContainsKey(visibility) && visibilityDictionary[visibility] != null)
+ {
+ writer.WriteKeyword(visibilityDictionary[visibility]);
+ writer.WriteString(" ");
+ }
+
+ }
+
+ // Write member | abstract | override
+ private void WriteMemberKeyword(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ bool isOverride = (bool)reflection.Evaluate(apiIsOverrideExpression);
+ bool isAbstract = (bool)reflection.Evaluate(apiIsAbstractProcedureExpression);
+
+ if (isOverride)
+ {
+ writer.WriteKeyword("override");
+ }
+ else if (isAbstract)
+ {
+ writer.WriteKeyword("abstract");
+ }
+ else
+ {
+ writer.WriteKeyword("member");
+ }
+ writer.WriteString(" ");
+
+ return;
+ }
+
+ // Attributes
+
+ private void WriteAttribute(string reference, SyntaxWriter writer)
+ {
+ writer.WriteString("[<");
+ writer.WriteReferenceLink(reference);
+ writer.WriteString(">]");
+ writer.WriteLine();
+ }
+
+
+ // Initial version
+ private void WriteAttributes(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ XPathNodeIterator attributes = (XPathNodeIterator)reflection.Evaluate(apiAttributesExpression);
+
+ foreach (XPathNavigator attribute in attributes)
+ {
+
+ XPathNavigator type = attribute.SelectSingleNode(attributeTypeExpression);
+ if (type.GetAttribute("api", String.Empty) == "T:System.Runtime.CompilerServices.ExtensionAttribute") continue;
+
+ writer.WriteString("[<");
+ WriteTypeReference(type, 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(" ");
+ }
+ }
+ 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(" ");
+ }
+ }
+ 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("null");
+ break;
+ case "typeValue":
+ writer.WriteKeyword("typeof");
+ writer.WriteString("(");
+ WriteTypeReference(value.SelectSingleNode(typeExpression), 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("\"");
+ 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("'");
+ writer.WriteString(text);
+ writer.WriteString("'");
+ break;
+ }
+ break;
+ }
+ }
+
+
+ // Generics
+
+ private void WriteGenericTemplates(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ XPathNodeIterator templates = (XPathNodeIterator)reflection.Evaluate(apiTemplatesExpression);
+
+ if (templates.Count == 0) return;
+ writer.WriteString("<");
+ while (templates.MoveNext())
+ {
+ XPathNavigator template = templates.Current;
+ string name = template.GetAttribute("name", String.Empty);
+ writer.WriteString("'");
+ writer.WriteString(name);
+ if (templates.CurrentPosition < templates.Count) writer.WriteString(", ");
+ }
+ WriteGenericTemplateConstraints(reflection, writer);
+ writer.WriteString(">");
+ }
+
+ private void WriteGenericTemplateConstraints(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ XPathNodeIterator templates = reflection.Select(apiTemplatesExpression);
+
+ if (templates.Count == 0) return;
+
+ foreach (XPathNavigator template in templates)
+ {
+
+ bool constrained = (bool)template.Evaluate(templateIsConstrainedExpression);
+ if (constrained)
+ {
+ string name = (string)template.Evaluate(templateNameExpression);
+
+ writer.WriteString(" ");
+ writer.WriteKeyword("when");
+ writer.WriteString(" '");
+ writer.WriteString(name);
+ writer.WriteString(" : ");
+ }
+ else
+ {
+ continue;
+ }
+
+ 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("struct");
+ previous = true;
+ }
+
+ if (reference)
+ {
+ if (previous) writer.WriteString(", ");
+ writer.WriteKeyword("not struct");
+ previous = true;
+ }
+
+ if (constructor)
+ {
+ if (previous) writer.WriteString(", ");
+ writer.WriteKeyword("new");
+ writer.WriteString("()");
+ previous = true;
+ }
+
+ foreach (XPathNavigator constraint in constraints)
+ {
+ if (previous) writer.WriteString(" and ");
+ WriteTypeReference(constraint, writer);
+ previous = true;
+ }
+
+ }
+
+ }
+
+ // Parameters
+
+ private void WriteParameters(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ if (parameters.Count > 0)
+ {
+ WriteParameters(parameters, reflection, writer);
+ }
+ else
+ {
+ writer.WriteKeyword("unit");
+ writer.WriteString(" ");
+ }
+ return;
+ }
+
+
+
+ private void WriteParameters(XPathNodeIterator parameters, XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ bool isExtension = (bool)reflection.Evaluate(apiIsExtensionMethod);
+ writer.WriteLine();
+
+
+ while (parameters.MoveNext())
+ {
+ XPathNavigator parameter = parameters.Current;
+
+ string name = (string)parameter.Evaluate(parameterNameExpression);
+ bool isOut = (bool)parameter.Evaluate(parameterIsOutExpression);
+ bool isRef = (bool)parameter.Evaluate(parameterIsRefExpression);
+ XPathNavigator type = parameter.SelectSingleNode(parameterTypeExpression);
+ writer.WriteString(" ");
+ writer.WriteParameter(name);
+ writer.WriteString(":");
+ WriteTypeReference(type, writer);
+ if (isOut || isRef)
+ {
+ writer.WriteString(" ");
+ writer.WriteKeyword("byref");
+ }
+ if (parameters.CurrentPosition != parameters.Count)
+ {
+ writer.WriteString(" * ");
+ writer.WriteLine();
+ }
+ else
+ {
+ writer.WriteString(" ");
+ }
+ }
+
+ }
+
+ // Return Value
+
+ private void WriteReturnValue(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ if (type == null)
+ {
+ writer.WriteKeyword("unit");
+ }
+ else
+ {
+ WriteTypeReference(type, writer);
+ }
+ }
+
+ // References
+
+ private void WriteTypeReference(XPathNavigator reference, SyntaxWriter writer)
+ {
+ switch (reference.LocalName)
+ {
+ case "arrayOf":
+ int rank = Convert.ToInt32(reference.GetAttribute("rank", String.Empty));
+ XPathNavigator element = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(element, writer);
+ writer.WriteString("[");
+ for (int i = 1; i < rank; i++) { writer.WriteString(","); }
+ writer.WriteString("]");
+ break;
+ case "pointerTo":
+ XPathNavigator pointee = reference.SelectSingleNode(typeExpression);
+ writer.WriteKeyword("nativeptr");
+ writer.WriteString("<");
+ WriteTypeReference(pointee, writer);
+ writer.WriteString(">");
+ break;
+ case "referenceTo":
+ XPathNavigator referee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(referee, writer);
+ break;
+ case "type":
+ string id = reference.GetAttribute("api", String.Empty);
+ WriteNormalTypeReference(id, writer);
+ XPathNodeIterator typeModifiers = reference.Select(typeModifiersExpression);
+ while (typeModifiers.MoveNext())
+ {
+ WriteTypeReference(typeModifiers.Current, writer);
+ }
+ break;
+ case "template":
+ string name = reference.GetAttribute("name", String.Empty);
+ writer.WriteString("'");
+ 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;
+ }
+ }
+
+ // DONE
+ private void WriteNormalTypeReference(string api, SyntaxWriter writer)
+ {
+ switch (api)
+ {
+ case "T:System.Void":
+ writer.WriteReferenceLink(api, "unit");
+ break;
+ case "T:System.String":
+ writer.WriteReferenceLink(api, "string");
+ break;
+ case "T:System.Boolean":
+ writer.WriteReferenceLink(api, "bool");
+ break;
+ case "T:System.Byte":
+ writer.WriteReferenceLink(api, "byte");
+ break;
+ case "T:System.SByte":
+ writer.WriteReferenceLink(api, "sbyte");
+ break;
+ case "T:System.Char":
+ writer.WriteReferenceLink(api, "char");
+ break;
+ case "T:System.Int16":
+ writer.WriteReferenceLink(api, "int16");
+ break;
+ case "T:System.Int32":
+ writer.WriteReferenceLink(api, "int");
+ break;
+ case "T:System.Int64":
+ writer.WriteReferenceLink(api, "int64");
+ break;
+ case "T:System.UInt16":
+ writer.WriteReferenceLink(api, "uint16");
+ break;
+ case "T:System.UInt32":
+ writer.WriteReferenceLink(api, "uint32");
+ break;
+ case "T:System.UInt64":
+ writer.WriteReferenceLink(api, "uint64");
+ break;
+ case "T:System.Single":
+ writer.WriteReferenceLink(api, "float32");
+ break;
+ case "T:System.Double":
+ writer.WriteReferenceLink(api, "float");
+ break;
+ case "T:System.Decimal":
+ writer.WriteReferenceLink(api, "decimal");
+ break;
+ default:
+ writer.WriteReferenceLink(api);
+ break;
+ }
+ }
+
+
+ }
+
+}