예제 #1
0
        private Task WriteExtensionWrapperFiles([NotNull] string extensionName, [NotNull] string wrappersOutputDirectory)
        {
            var translatedExtensionName  = _identifierTranslator.Translate(extensionName);
            var extensionOutputDirectory = Path.Combine(wrappersOutputDirectory, translatedExtensionName);

            if (!Directory.Exists(extensionOutputDirectory))
            {
                Directory.CreateDirectory(extensionOutputDirectory);
            }

            var allCategories = _profile.GetCategories();
            var categoryTasks = allCategories.Select(category => Task.Run(() => WriteCategoryWrapperFile(extensionOutputDirectory, extensionName, category)));

            return(Task.WhenAll(categoryTasks));
        }
예제 #2
0
        private TypeSignature MapGenericEnumerationType
        (
            [NotNull] ApiProfile profile,
            [NotNull] FunctionSignature containingFunction,
            [NotNull] TypeSignature baseParameterType
        )
        {
            foreach (var categoryName in containingFunction.Categories)
            {
                var translatedName = _identifierTranslator.Translate(categoryName);

                var genericEnumeration = profile.Enumerations.FirstOrDefault(e => e.Name == translatedName);
                if (!(genericEnumeration is null))
                {
                    return(new TypeSignatureBuilder(baseParameterType).WithName(genericEnumeration.Name).Build());
                }
            }

            // No enumeration found, falling back to a simple integer
            return(new TypeSignatureBuilder(baseParameterType).WithName("uint").Build());
        }
        /// <summary>
        /// Appends the contents of a constant value node, transformed into its best-matching XMLDoc equivalent.
        /// </summary>
        /// <param name="descriptionBuilder">The builder to append to.</param>
        /// <param name="function">The function the node is in.</param>
        /// <param name="parameter">The parameter the node is in.</param>
        /// <param name="constantNode">The node.</param>
        /// <param name="greedilyConsumedNodes">Nodes that have been greedily consumed.</param>
        private void AppendConstantNode
        (
            [NotNull] StringBuilder descriptionBuilder,
            [NotNull] FunctionDocumentation function,
            [NotNull] ParameterDocumentation parameter,
            [NotNull] XElement constantNode,
            [NotNull, ItemNotNull] ICollection <XNode> greedilyConsumedNodes
        )
        {
            var constantName = constantNode.Value;

            if (constantName.StartsWith("GL_"))
            {
                // It's an enum - transform its name, and look it up
                var translatedName = _identifierTranslator.Translate
                                     (
                    constantName.Remove(0, 3)
                                     );

                // Arbitrary number handling
                string arbitraryNumberName      = null;
                var    hasArbitraryNumberInsert = false;
                if (translatedName.EndsWith("i"))
                {
                    translatedName           = translatedName.Remove(translatedName.Length - 1);
                    hasArbitraryNumberInsert = true;
                    arbitraryNumberName      = "i";
                }

                var hasEmphasizedNumberInsert = constantNode.NextNode is XElement emphasisNode &&
                                                (emphasisNode.Attribute("class")?.Value == "emphasis" ||
                                                 emphasisNode.Attribute("class")?.Value == "replaceable");
                if (hasEmphasizedNumberInsert)
                {
                    var nextNode = (XElement)constantNode.NextNode;
                    arbitraryNumberName      = nextNode.Value;
                    hasArbitraryNumberInsert = true;
                }

                // See if it's followed by a number (emphasized)
                if (hasArbitraryNumberInsert)
                {
                    // It is a number, so we'll just stick a 0 on the end as a stand-in
                    translatedName = $"{translatedName}0";
                }

                if (hasEmphasizedNumberInsert)
                {
                    greedilyConsumedNodes.Add(constantNode.NextNode);
                }

                // See if we can find the name of the enum that the constant is in
                // Look up the function that the parameter is in
                var functionNameWithoutPrefix = new string(function.Name.SkipWhile(char.IsLower).ToArray());

                var actualFunction =
                    _apiProfile.FindFunctionWithEntrypoint(functionNameWithoutPrefix);

                if (actualFunction is null)
                {
                    throw new InvalidOperationException
                          (
                              $"Could not find a function named \"{functionNameWithoutPrefix}\""
                          );
                }

                var actualParameter =
                    actualFunction.Parameters.FirstOrDefault(p => p.Name == parameter.Name);

                var typeName = actualParameter?.Type.Name;
                if (typeName is null)
                {
                    Debug.WriteLine
                    (
                        $"Could not find the parameter named \"{parameter.Name}\" in " +
                        $"\"{actualFunction.Name}\". Consider adding a name override to " +
                        $"match the documentation."
                    );
                }

                if (typeName is null || _apiProfile.Enumerations.All(e => e.Name != typeName))
                {
                    var containingEnum = _apiProfile.FindContainingEnumeration(translatedName);
                    if (containingEnum is null)
                    {
                        typeName = "Unknown";
                    }
                    else
                    {
                        typeName = containingEnum.Name;
                    }

                    Debug.WriteLine
                    (
                        $"Falling back to a manual enum type search for " +
                        $"\"{translatedName}\"."
                    );
                }

                descriptionBuilder.Append
                (
                    $"<see cref=\"{typeName}.{translatedName}\"/>"
                );

                if (hasArbitraryNumberInsert)
                {
                    descriptionBuilder.Append($" (consider 0 as <i>{arbitraryNumberName}</i>)");
                }
            }
            else
            {
                // It's a constant value of some sort - transform it to lower, and inline
                descriptionBuilder.Append
                (
                    $"<value>{constantName.Transform(To.LowerCase)}</value>"
                );
            }
        }