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)); }
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>" ); } }