summaryrefslogtreecommitdiffstats
path: root/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/ScriptSharpDeclarationSyntax.cs
diff options
context:
space:
mode:
Diffstat (limited to 'tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/ScriptSharpDeclarationSyntax.cs')
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/ScriptSharpDeclarationSyntax.cs611
1 files changed, 611 insertions, 0 deletions
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/ScriptSharpDeclarationSyntax.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/ScriptSharpDeclarationSyntax.cs
new file mode 100644
index 0000000..e0f3c07
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/ScriptSharpDeclarationSyntax.cs
@@ -0,0 +1,611 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+using System;
+using System.Xml.XPath;
+using System.Globalization;
+
+namespace Microsoft.Ddue.Tools {
+ /// <summary>
+ /// Generates syntax that corresponds to JavaScript that Script# generates.
+ /// </summary>
+ public class ScriptSharpDeclarationSyntaxGenerator : SyntaxGeneratorTemplate {
+ private static readonly XPathExpression typeIsRecordExpression = XPathExpression.Compile("boolean(apidata/@record)");
+
+ private static readonly XPathExpression memberIsGlobalExpression = XPathExpression.Compile("boolean(apidata/@global)");
+
+ /// <summary>
+ /// Initializes a new instance of the <c>ScriptSharpDeclarationSyntaxGenerator</c> class.
+ /// </summary>
+ /// <param name="configuration"></param>
+ public ScriptSharpDeclarationSyntaxGenerator(XPathNavigator configuration) : base(configuration) {
+ if (String.IsNullOrEmpty(language)) language = "JavaScript";
+ }
+
+ /// <summary>
+ /// Determines whether the feature is unsupported by this language.
+ /// </summary>
+ /// <param name="reflection"></param>
+ /// <param name="writer"></param>
+ /// <returns></returns>
+ private bool IsUnsupported(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupportedGeneric(reflection, writer)) {
+ return true;
+ }
+
+ if (IsUnsupportedExplicit(reflection, writer)) {
+ return true;
+ }
+
+ if (IsUnsupportedUnsafe(reflection, writer)) {
+ return true;
+ }
+
+ if (HasAttribute(reflection, "System.NonScriptableAttribute")) {
+ writer.WriteMessage("UnsupportedType_ScriptSharp");
+ return true;
+ }
+
+ return false;
+ }
+
+ private string ReadNamespaceName(XPathNavigator reflection) {
+ return (string)reflection.Evaluate(apiContainingNamespaceNameExpression);
+ }
+
+ private string ReadTypeName(XPathNavigator reflection) {
+ return (string)reflection.Evaluate(apiNameExpression);
+ }
+
+ private string ReadContainingTypeName(XPathNavigator reflection) {
+ return (string)reflection.Evaluate(apiContainingTypeNameExpression);
+ }
+
+ private string ReadFullTypeName(XPathNavigator reflection) {
+ string namespaceName = ReadNamespaceName(reflection);
+
+ string typeName = ReadTypeName(reflection);
+
+ if (String.IsNullOrEmpty(namespaceName) || HasAttribute(reflection, "System.IgnoreNamespaceAttribute")) {
+ return typeName;
+ }
+ else {
+ return String.Format("{0}.{1}", namespaceName, typeName);
+ }
+ }
+
+ private string ReadFullContainingTypeName(XPathNavigator reflection) {
+ string namespaceName = ReadNamespaceName(reflection);
+
+ string typeName = ReadContainingTypeName(reflection);
+
+ if (String.IsNullOrEmpty(namespaceName) || HasAttribute(reflection, "System.IgnoreNamespaceAttribute")) {
+ return typeName;
+ }
+ else {
+ return String.Format("{0}.{1}", namespaceName, typeName);
+ }
+ }
+
+ private string ReadMemberName(XPathNavigator reflection) {
+ string identifier = (string)reflection.Evaluate(apiNameExpression);
+
+ if (!HasAttribute(reflection, "System.PreserveCaseAttribute")) {
+ identifier = CreateCamelCaseName(identifier);
+ }
+
+ return identifier;
+ }
+
+ private bool HasAttribute(XPathNavigator reflection, string attributeName) {
+ attributeName = "T:" + attributeName;
+
+ XPathNodeIterator iterator = (XPathNodeIterator)reflection.Evaluate(apiAttributesExpression);
+ foreach (XPathNavigator navigator in iterator) {
+ XPathNavigator reference = navigator.SelectSingleNode(attributeTypeExpression);
+ if (reference.GetAttribute("api", string.Empty) == attributeName) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static string CreateCamelCaseName(string name) {
+
+ if (String.IsNullOrEmpty(name)) {
+ return name;
+ }
+
+ // Some exceptions that simply need to be special cased
+ if (name.Equals("ID", StringComparison.Ordinal)) {
+ return "id";
+ }
+
+ bool hasLowerCase = false;
+ int conversionLength = 0;
+
+ for (int i = 0; i < name.Length; i++) {
+ if (Char.IsUpper(name, i)) {
+ conversionLength++;
+ } else {
+ hasLowerCase = true;
+ break;
+ }
+ }
+
+ if (((hasLowerCase == false) && (name.Length != 1)) || (conversionLength == 0)) {
+ // Name is all upper case, or all lower case; leave it as-is.
+ return name;
+ }
+
+ if (conversionLength > 1) {
+ // Convert the leading uppercase segment, except the last character
+ // which is assumed to be the first letter of the next word
+ return name.Substring(0, conversionLength - 1).ToLower(CultureInfo.InvariantCulture) + name.Substring(conversionLength - 1);
+ }
+
+ else if (name.Length == 1) {
+ return name.ToLower(CultureInfo.InvariantCulture);
+ }
+
+ else {
+ // Convert the leading upper case character to lower case
+ return Char.ToLower(name[0], CultureInfo.InvariantCulture) + name.Substring(1);
+ }
+ }
+
+ private void WriteIndentedNewLine(SyntaxWriter writer) {
+ writer.WriteString(",");
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+
+ private void WriteParameterList(XPathNavigator reflection, SyntaxWriter writer) {
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+ writer.WriteString("(");
+
+ while (parameters.MoveNext()) {
+ XPathNavigator parameter = parameters.Current;
+
+ WriteParameter(parameter, writer);
+ if (parameters.CurrentPosition < parameters.Count) {
+ writer.WriteString(", ");
+ }
+ }
+ writer.WriteString(")");
+ }
+
+ private void WriteParameter(XPathNavigator parameter, SyntaxWriter writer) {
+ string text = (string)parameter.Evaluate(parameterNameExpression);
+ XPathNavigator reference = parameter.SelectSingleNode(parameterTypeExpression);
+ if ((bool)parameter.Evaluate(parameterIsParamArrayExpression)) {
+ writer.WriteString("... ");
+ }
+ writer.WriteParameter(text);
+ }
+
+ private void WriteTypeReference(XPathNavigator reference, SyntaxWriter writer)
+ {
+ switch (reference.LocalName)
+ {
+ case "arrayOf":
+ int rank = Convert.ToInt32(reference.GetAttribute("rank", string.Empty));
+ XPathNavigator navigator = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(navigator, writer);
+ writer.WriteString("[");
+ for (int i = 1; i < rank; i++) { writer.WriteString(","); }
+ writer.WriteString("]");
+ break;
+ case "type":
+ string id = reference.GetAttribute("api", string.Empty);
+ WriteNormalTypeReference(id, writer);
+ break;
+ case "pointerTo":
+ case "referenceTo":
+ case "template":
+ case "specialization":
+ // Not supported
+ break;
+ }
+ }
+
+ private void WriteNormalTypeReference(string api, SyntaxWriter writer) {
+ switch (api) {
+ case "T:System.Byte":
+ writer.WriteReferenceLink(api, "Byte");
+ return;
+
+ case "T:System.SByte":
+ writer.WriteReferenceLink(api, "SByte");
+ return;
+
+ case "T:System.Char":
+ writer.WriteReferenceLink(api, "Char");
+ return;
+
+ case "T:System.Int16":
+ writer.WriteReferenceLink(api, "Int16");
+ return;
+
+ case "T:System.Int32":
+ writer.WriteReferenceLink(api, "Int32");
+ return;
+
+ case "T:System.Int64":
+ writer.WriteReferenceLink(api, "Int64");
+ return;
+
+ case "T:System.UInt16":
+ writer.WriteReferenceLink(api, "UInt16");
+ return;
+
+ case "T:System.UInt32":
+ writer.WriteReferenceLink(api, "UInt32");
+ return;
+
+ case "T:System.UInt64":
+ writer.WriteReferenceLink(api, "UInt64");
+ return;
+
+ case "T:System.Single":
+ writer.WriteReferenceLink(api, "Single");
+ return;
+
+ case "T:System.Double":
+ writer.WriteReferenceLink(api, "Double");
+ return;
+
+ case "T:System.Decimal":
+ writer.WriteReferenceLink(api, "Decimal");
+ return;
+
+ case "T:System.Boolean":
+ writer.WriteReferenceLink(api, "Boolean");
+ return;
+ }
+
+ // Remove 'T:'
+ string name = api.Substring(2);
+
+ // Strip System namespaces
+ if (name.StartsWith("System.")) {
+ int idx = name.LastIndexOf('.');
+ name = name.Substring(idx + 1);
+ }
+
+ writer.WriteReferenceLink(api, name);
+ }
+
+ private void WriteRecordSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ string namespaceName = ReadNamespaceName(reflection);
+
+ string typeName = ReadTypeName(reflection);
+
+ writer.WriteString(namespaceName);
+ writer.WriteString(".$create_");
+ writer.WriteString(typeName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ writer.WriteString("();");
+ }
+
+ private void WriteRecordConstructorSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ string namespaceName = ReadNamespaceName(reflection);
+
+ string typeName = ReadContainingTypeName(reflection);
+
+ writer.WriteString(namespaceName);
+ writer.WriteString(".$create_");
+ writer.WriteString(typeName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ WriteParameterList(reflection, writer);
+ writer.WriteString(";");
+ }
+
+ public override void WriteClassSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) return;
+
+ if (HasAttribute(reflection, "System.RecordAttribute")) {
+ WriteRecordSyntax(reflection, writer);
+ return;
+ }
+
+ string typeName = ReadFullTypeName(reflection);
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ writer.WriteString("();");
+
+ writer.WriteLine();
+ writer.WriteLine();
+
+ writer.WriteIdentifier("Type");
+ writer.WriteString(".createClass(");
+ writer.WriteLine();
+ writer.WriteString("\t'");
+ writer.WriteString(typeName);
+ writer.WriteString("'");
+
+ bool hasBaseClass = false;
+
+ // Write the base class.
+ XPathNavigator reference = reflection.SelectSingleNode(apiBaseClassExpression);
+ if (!((reference == null) || ((bool)reference.Evaluate(typeIsObjectExpression)))) {
+ WriteIndentedNewLine(writer);
+ WriteTypeReference(reference, writer);
+ hasBaseClass = true;
+ }
+
+ // Write the interfaces.
+ XPathNodeIterator iterator = reflection.Select(apiImplementedInterfacesExpression);
+ if (iterator.Count != 0) {
+ if (!hasBaseClass) {
+ WriteIndentedNewLine(writer);
+ writer.WriteString("null");
+ }
+
+ WriteIndentedNewLine(writer);
+
+ while (iterator.MoveNext()) {
+ XPathNavigator interfaceRef = iterator.Current;
+ WriteTypeReference(interfaceRef, writer);
+ if (iterator.CurrentPosition < iterator.Count) {
+ WriteIndentedNewLine(writer);
+ }
+ }
+ }
+
+ writer.WriteString(");");
+ }
+
+ public override void WriteConstructorSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) {
+ return;
+ }
+
+ bool isRecord = (bool)reflection.Evaluate(typeIsRecordExpression);
+
+ if (isRecord) {
+ WriteRecordConstructorSyntax(reflection, writer);
+ return;
+ }
+
+ string typeName = ReadFullContainingTypeName(reflection);
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ WriteParameterList(reflection, writer);
+ writer.WriteString(";");
+ }
+
+ public override void WriteNormalMethodSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) return;
+
+ if (HasAttribute(reflection, "System.AttachedPropertyAttribute")) {
+ WriteAttachedPropertySyntax(reflection, writer);
+ return;
+ }
+
+ string memberName = ReadMemberName(reflection);
+
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isGlobal = (bool)reflection.Evaluate(memberIsGlobalExpression);
+
+ if (isStatic && !isGlobal) {
+ writer.WriteIdentifier(ReadFullContainingTypeName(reflection));
+ writer.WriteString(".");
+ writer.WriteIdentifier(memberName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ }
+ else {
+ writer.WriteKeyword("function");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(memberName);
+ }
+
+ WriteParameterList(reflection, writer);
+ writer.WriteString(";");
+ }
+
+ public override void WriteDelegateSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ writer.WriteKeyword("function");
+ WriteParameterList(reflection, writer);
+ writer.WriteString(";");
+ }
+
+ public override void WriteEnumerationSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ string typeName = ReadFullTypeName(reflection);
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ writer.WriteString("();");
+
+ writer.WriteLine();
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(".createEnum('");
+ writer.WriteIdentifier(typeName);
+ writer.WriteString("', ");
+ writer.WriteString(HasAttribute(reflection, "System.FlagsAttribute") ? "true" : "false");
+ writer.WriteString(");");
+ }
+
+ public override void WriteEventSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) return;
+
+ if (reflection.Select(apiParametersExpression).Count > 0) {
+ writer.WriteMessage("UnsupportedIndex_" + Language);
+ return;
+ }
+
+ string memberName = ReadMemberName(reflection);
+
+ writer.WriteKeyword("function");
+ writer.WriteString(" add_");
+ writer.WriteIdentifier(memberName);
+ writer.WriteString("(");
+ writer.WriteParameter("value");
+ writer.WriteString(");");
+
+ writer.WriteLine();
+
+ writer.WriteKeyword("function");
+ writer.WriteString(" remove_");
+ writer.WriteIdentifier(memberName);
+ writer.WriteString("(");
+ writer.WriteParameter("value");
+ writer.WriteString(");");
+ }
+
+ public override void WriteFieldSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ if (IsUnsupported(reflection, writer)) {
+ return;
+ }
+
+ string memberName = ReadMemberName(reflection);
+
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ if (isStatic) {
+ string typeName = ReadFullContainingTypeName(reflection);
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(".");
+ }
+
+ writer.WriteIdentifier(memberName);
+ }
+
+ public override void WriteInterfaceSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) return;
+
+ string typeName = ReadFullTypeName(reflection);
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ writer.WriteString("();");
+
+ writer.WriteLine();
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(".createInterface('");
+ writer.WriteIdentifier(typeName);
+ writer.WriteString("');");
+ }
+
+ public override void WriteAttachedEventSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ // Not supported
+ }
+
+ public override void WriteAttachedPropertySyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ string typeName = ReadContainingTypeName(reflection);
+
+ string methodName = ReadMemberName(reflection);
+
+ string propertyName = String.Format("{0}.{1}", typeName, methodName.Substring(3));
+
+ if (methodName.StartsWith("Get", StringComparison.OrdinalIgnoreCase)) {
+ writer.WriteKeyword("var");
+ writer.WriteString(" value = obj['");
+ writer.WriteString(propertyName);
+ writer.WriteString("'];");
+ }
+ else if (methodName.StartsWith("Set", StringComparison.OrdinalIgnoreCase)) {
+ writer.WriteString("obj['");
+ writer.WriteString(propertyName);
+ writer.WriteString("'] = value;");
+ }
+ }
+
+ public override void WriteOperatorSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ writer.WriteMessage("UnsupportedOperator_" + Language);
+ }
+
+ public override void WriteCastSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ writer.WriteMessage("UnsupportedCast_" + Language);
+ }
+
+ public override void WriteNamespaceSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ string name = reflection.Evaluate(apiNameExpression).ToString();
+
+ writer.WriteString("Type.createNamespace('");
+ writer.WriteIdentifier(name);
+ writer.WriteString("');");
+ }
+
+ public override void WritePropertySyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) return;
+
+ if (HasAttribute(reflection, "System.IntrinsicPropertyAttribute")) {
+ WriteFieldSyntax(reflection, writer);
+ return;
+ }
+
+ string memberName = ReadMemberName(reflection);
+
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+
+ bool isGetter = (bool)reflection.Evaluate(apiIsReadPropertyExpression);
+ bool isSetter = (bool)reflection.Evaluate(apiIsWritePropertyExpression);
+
+ XPathNavigator reference = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ if (isGetter) {
+ if (isStatic) {
+ writer.WriteIdentifier(ReadFullContainingTypeName(reflection));
+ writer.WriteString(".");
+
+ writer.WriteString("get_");
+ writer.WriteIdentifier(memberName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ }
+ else {
+ writer.WriteKeyword("function");
+ writer.WriteString(" ");
+
+ writer.WriteString("get_");
+ writer.WriteIdentifier(memberName);
+ }
+
+ WriteParameterList(reflection, writer);
+ writer.WriteString(";");
+ writer.WriteLine();
+ }
+
+ if (isSetter) {
+ if (isStatic) {
+ writer.WriteIdentifier(ReadFullContainingTypeName(reflection));
+ writer.WriteString(".");
+
+ writer.WriteString("set_");
+ writer.WriteIdentifier(memberName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ }
+ else {
+ writer.WriteKeyword("function");
+ writer.WriteString(" ");
+
+ writer.WriteString("set_");
+ writer.WriteIdentifier(memberName);
+ }
+
+ writer.WriteString("(");
+ writer.WriteParameter("value");
+ writer.WriteString(");");
+ }
+ }
+
+ public override void WriteStructureSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) return;
+ writer.WriteMessage("UnsupportedStructure_" + Language);
+ }
+ }
+} \ No newline at end of file