public static void ApplyBuiltinFixup(this XDocument document) { // add the gs namespace prefix document.Root.SetAttributeValue(XNamespace.Xmlns + "gs", gs.NamespaceName); // remove all elements marked as "skip", "moved-to" or "shadowed-by" // and functions/methods with varagrs. On OS X/homebrew, there are // aliases that end with _autoptr that need to be ignored too. var elementsToRemove = document.Descendants() .Where(d => d.Name != gi + "return-value" && d.Name != gi + "parameter") .Where(d => d.Attribute("skip").AsBool() || d.Attribute("moved-to") != null || d.Attribute("shadowed-by") != null || d.IsCallableWithVarArgs() || d.Attribute("name").AsString("").EndsWith("_autoptr", StringComparison.Ordinal)) .ToList(); foreach (var element in elementsToRemove) { element.Remove(); } // add functions for GType getters var elementsWithGTypeGetter = document.Descendants() .Where(d => d.Attribute(glib + "get-type").AsString("intern") != "intern"); foreach (var element in elementsWithGTypeGetter) { var functionElement = new XElement( gi + "function", new XAttribute("name", "_get_g_type"), new XAttribute(c + "identifier", element.Attribute(glib + "get-type").Value), new XAttribute(gs + "access-modifiers", "private"), new XElement( gi + "return-value", new XElement( gi + "type", new XAttribute("name", "GType")))); element.Add(functionElement); } // rename all error_quark functions to get_error_quark so that they // become properties var errorQuarkElements = document.Descendants(gi + "function") .Where(d => d.Attribute("name").Value.EndsWith("error_quark", StringComparison.Ordinal)); foreach (var element in errorQuarkElements) { if (element.Attribute("name").Value.StartsWith("get_", StringComparison.Ordinal)) { continue; } element.SetAttributeValue("name", "get_" + element.Attribute("name").Value); } // add value field to all alias elements var aliasElements = document.Descendants(gi + "alias"); foreach (var element in aliasElements) { var valueFieldElement = new XElement(gi + "field", new XAttribute("name", "value"), new XAttribute(gs + "access-modifiers", "private"), new XElement(element.Element(gi + "type"))); element.Add(valueFieldElement); } // add error parameters for anything that throws var elementsThatThrow = document.Descendants() .Where(d => d.Attribute("throws") != null); foreach (var element in elementsThatThrow) { var errorElement = new XElement(gs + "error-parameter", new XAttribute("name", "error"), new XAttribute("direction", "out"), new XAttribute(gs + "managed-type", typeof(IntPtr).FullName), new XElement(gi + "doc", "return location for a #GError"), new XElement(gi + "type", new XAttribute("name", "GLib.Error"))); if (element.Element(gi + "parameters") == null) { element.Add(new XElement(gi + "parameters")); } element.Element(gi + "parameters").Add(errorElement); } // create managed-name attributes foreach (var element in document.Descendants()) { if (element.Attribute(gs + "managed-name") != null) { continue; } if (element.Name == gi + "return-value") { element.SetAttributeValue(gs + "managed-name", "ret"); continue; } var attr = element.Attribute("name"); if (attr == null) { continue; } var name = attr.Value; // replace name by shadows if it exists (i.e. drop _full suffix) var shadows = element.Attribute("shadows"); if (shadows != null) { name = shadows.Value; } // check various conditions where we might want camelCase var camelCase = false; var accessModifier = element.Attribute(gs + "access-modifiers"); if (accessModifier != null) { camelCase = accessModifier.Value.Contains("private"); } if (element.Name == gi + "parameter" || element.Name == gi + "instance-parameter" || element.Name == gs + "error-parameter") { camelCase = true; } name = camelCase ? name.ToCamelCase() : name.ToPascalCase(); // callbacks that are defined for a field tend to have name conflicts if (element.Name == gi + "field" && element.Element(gi + "callback") != null) { // add "Impl" suffix to the field name name += "Impl"; } element.SetAttributeValue(gs + "managed-name", name); } // flag extension methods var elementNamesThatRequireExtensionMethods = new [] { gi + "enumeration", gi + "bitfield", gi + "interface", }; var elementsThatRequireExtensionMethods = document.Descendants(gi + "method") .Where(e => elementNamesThatRequireExtensionMethods.Contains(e.Parent.Name)); foreach (var element in elementsThatRequireExtensionMethods) { element.SetAttributeValue(gs + "extension-method", "1"); } // flag ref functions var elementsWithRefMethod = document.Descendants(gi + "method") .Where(d => d.Attribute("name").Value == "ref" && !d.Element(gi + "parameters").Elements(gi + "parameter").Any()); foreach (var element in elementsWithRefMethod) { element.SetAttributeValue(gs + "special-func", "ref"); element.SetAttributeValue(gs + "access-modifiers", "public override"); element.Element(gi + "return-value").SetAttributeValue("skip", "1"); } // flag unref functions var elementsWithUnrefMethod = document.Descendants(gi + "method") .Where(d => d.Attribute("name").Value == "unref" && !d.Element(gi + "parameters").Elements(gi + "parameter").Any()); foreach (var element in elementsWithUnrefMethod) { element.SetAttributeValue(gs + "special-func", "unref"); element.SetAttributeValue(gs + "access-modifiers", "public override"); } // flag free functions var elementsWithFreeMethod = document.Descendants(gi + "method") .Where(d => d.Attribute("name").Value == "free" && !d.Element(gi + "parameters").Elements(gi + "parameter").Any()); foreach (var element in elementsWithFreeMethod) { element.SetAttributeValue(gs + "special-func", "free"); element.SetAttributeValue(gs + "access-modifiers", "protected override"); } // flag equals functions var elementsWithEqualsFunction = document.Descendants(gi + "method") .Where(d => d.Attribute("name").Value == "equal" && d.Element(gi + "parameters").Elements(gi + "parameter").Count() == 1); foreach (var element in elementsWithEqualsFunction) { element.SetAttributeValue(gs + "special-func", "equal"); element.SetAttributeValue(gs + "managed-name", "Equals"); } // flag compare functions var elementsWithCompareFunction = document.Descendants(gi + "method") .Where(d => d.Attribute("name").Value == "compare" && d.Element(gi + "parameters").Elements(gi + "parameter").Count() == 1); foreach (var element in elementsWithCompareFunction) { element.SetAttributeValue(gs + "special-func", "compare"); element.SetAttributeValue(gs + "managed-name", "CompareTo"); } // flag hash functions var elementsWithHashFunction = document.Descendants(gi + "method") .Where(d => d.Attribute("name").Value == "hash" && !d.Element(gi + "parameters").Elements(gi + "parameter").Any() && d.Element(gi + "return-value").Element(gi + "type") != null && d.Element(gi + "return-value").Element(gi + "type").Attribute("name").Value == "guint"); foreach (var element in elementsWithHashFunction) { element.SetAttributeValue(gs + "special-func", "hash"); element.SetAttributeValue(gs + "access-modifiers", "public override"); // set managed-name here so it don't get turned into a property getter element.SetAttributeValue(gs + "managed-name", "GetHashCode"); // change return type to match .NET element.Element(gi + "return-value").Element(gi + "type").SetAttributeValue("name", "gint"); } // flag to_string functions var elementsWithToStringFunction = document.Descendants(gi + "method") .Where(d => d.Attribute("name").Value == "to_string" && !d.Element(gi + "parameters").Elements(gi + "parameter").Any()); foreach (var element in elementsWithToStringFunction) { element.SetAttributeValue(gs + "special-func", "to-string"); element.SetAttributeValue(gs + "access-modifiers", "public override"); } // flag reference-counted opaques var recordsThatAreRefCounted = document.Descendants(gi + "record") .Where(d => d.Elements(gi + "method").Any(m => m.Attribute(gs + "special-func").AsString() == "ref") && d.Elements(gi + "method").Any(m => m.Attribute(gs + "special-func").AsString() == "unref")); foreach (var element in recordsThatAreRefCounted) { element.SetAttributeValue(gs + "opaque", "ref-counted"); } // flag owned opaques var recordsThatAreOwned = document.Descendants(gi + "record") .Where(d => d.Elements(gi + "method").Any(m => m.Attribute(gs + "special-func").AsString() == "free")); foreach (var element in recordsThatAreOwned) { element.SetAttributeValue(gs + "opaque", "owned"); } // flag static opaques var recordsThatAreStatic = document.Descendants(gi + "record") .Where(d => d.Elements(gi + "constructor").Any(c => c.Attribute("name").AsString() == "new" && c.Element(gi + "return-value").Attribute("transfer-ownership").AsString() == "none")); foreach (var element in recordsThatAreStatic) { element.SetAttributeValue(gs + "opaque", "static"); } // flag gtype-struct opaques var recordsThatAreGTypeStructs = document.Descendants(gi + "record") .Where(d => d.Attribute(glib + "is-gtype-struct-for") != null); foreach (var element in recordsThatAreGTypeStructs) { element.SetAttributeValue(gs + "opaque", "gtype-struct"); } // move fields to internal struct in opaques var recordsThatAreOpaque = document.Descendants(gi + "record") .Where(d => d.Attribute(gs + "opaque") != null); foreach (var element in recordsThatAreOpaque) { var innerStruct = new XElement(gi + "record", new XAttribute("name", element.Attribute("name").Value + "Struct"), new XAttribute(gs + "managed-name", element.Attribute(gs + "managed-name").Value + "Struct"), new XAttribute(gs + "access-modifiers", "protected")); var fields = element.Elements(gi + "field").ToList(); foreach (var field in fields) { field.Remove(); innerStruct.Add(field); } element.AddFirst(innerStruct); } // remove fields from classes var classes = document.Descendants(gi + "class"); foreach (var element in classes) { var fields = element.Elements(gi + "field").ToList(); foreach (var field in fields) { field.Remove(); } } // add managed-type attribute (skipping existing managed-type attributes) var elementsWithManagedType = document.Descendants() .Where(d => ElementsThatReferenceAType.Contains(d.Name)) .Where(d => d.Attribute(gs + "managed-type") == null); foreach (var element in elementsWithManagedType) { var managedType = element.GetManagedTypeName(); element.SetAttributeValue(gs + "managed-type", managedType); } // add managed-parameters element var parameterElements = document.Descendants(gi + "parameters"); foreach (var element in parameterElements) { var managedParamtersElement = new XElement(gs + "managed-parameters"); foreach (var managedParameterElement in element.EnumerateManagedParameters()) { managedParamtersElement.Add(new XElement(managedParameterElement)); } element.Parent.Add(managedParamtersElement); } // flag getters as properties var getters = document.Descendants() .Where(d => (d.Name == gi + "function" || d.Name == gi + "method") && !d.Attribute(gs + "extension-method").AsBool() && !d.Attribute(gs + "pinvoke-only").AsBool() && (d.Attribute("name").Value.StartsWith("get_", StringComparison.Ordinal) || d.Attribute("name").Value.StartsWith("is_", StringComparison.Ordinal)) && (d.Element(gs + "managed-parameters") == null || !d.Element(gs + "managed-parameters").Elements(gi + "parameter").Any())); foreach (var element in getters) { var name = element.Attribute(gs + "managed-name").Value; if (element.Attribute("name").Value.StartsWith("get_", StringComparison.Ordinal)) { // drop the Get prefix, but not the Is name = name.Substring(3); } element.SetAttributeValue(gs + "property", name); element.SetAttributeValue(gs + "managed-name", "get_" + name); } // flag setters as properties (if there is a matching getter only) var setters = document.Descendants() .Where(d => (d.Name == gi + "function" || d.Name == gi + "method") && !d.Attribute(gs + "pinvoke-only").AsBool() && d.Attribute("name").Value.StartsWith("set_", StringComparison.Ordinal) && d.Element(gs + "managed-parameters") != null && d.Element(gs + "managed-parameters").Elements(gi + "parameter").Count() == 1); foreach (var element in setters) { var name = element.Attribute(gs + "managed-name").Value; // drop the Set prefix name = name.Substring(3); var matchingGetter = element.Parent.Elements(element.Name).SingleOrDefault(e => e.Attribute(gs + "property").AsString() == name); if (matchingGetter == null) { // we don't want set-only properties continue; } var getterReturnType = matchingGetter.Element(gi + "return-value").Attribute(gs + "managed-type").Value; var setterParameterType = element.Element(gs + "managed-parameters").Element(gi + "parameter").Attribute(gs + "managed-type").Value; if (getterReturnType != setterParameterType) { // this isn't the setter if the types don't match continue; } element.SetAttributeValue(gs + "property", name); element.SetAttributeValue(gs + "managed-name", "set_" + name); // rename the parameter to "value" since that is what the set accessor in C# requires element.Element(gs + "managed-parameters").Element(gi + "parameter").SetAttributeValue(gs + "managed-name", "value"); } }
private void UpdateXmlReferenceFromLastSection(XElement xml, IEnumerable <XElement> lastSectionsXml, bool isHeader) { if ((xml == null) || (lastSectionsXml == null) || (lastSectionsXml.Count() == 0)) { return; } var references = xml.Elements(XName.Get(isHeader ? "headerReference" : "footerReference", w.NamespaceName)); // First, Even, Odd(default) var definedReferenceTypes = new List <XElement>() { null, null, null }; foreach (var r in references) { var rType = r.Attribute(w + "type").Value; switch (rType) { case "first": definedReferenceTypes[0] = r; break; case "even": definedReferenceTypes[1] = r; break; default: definedReferenceTypes[2] = r; break; } } // Current section do not have a reference, copy the one from preceding sections, if available. if (definedReferenceTypes.Any(r => r == null)) { var lastSectionsXmlList = lastSectionsXml.ToList(); for (int i = lastSectionsXmlList.Count - 1; i >= 0; i--) { var lastSectionXml = lastSectionsXmlList[i]; var lastSectionReferences = lastSectionXml.Elements(XName.Get(isHeader ? "headerReference" : "footerReference", w.NamespaceName)); if (definedReferenceTypes[0] == null) { var lastSectionFirst = lastSectionReferences.FirstOrDefault(x => x.Attribute(w + "type").Value == "first"); if (lastSectionFirst != null) { xml.Add(lastSectionFirst); definedReferenceTypes[0] = lastSectionFirst; } } if (definedReferenceTypes[1] == null) { var lastSectionEven = lastSectionReferences.FirstOrDefault(x => x.Attribute(w + "type").Value == "even"); if (lastSectionEven != null) { xml.Add(lastSectionEven); definedReferenceTypes[1] = lastSectionEven; } } if (definedReferenceTypes[2] == null) { var lastSectionDefault = lastSectionReferences.FirstOrDefault(x => x.Attribute(w + "type").Value == "default"); if (lastSectionDefault != null) { xml.Add(lastSectionDefault); definedReferenceTypes[2] = lastSectionDefault; } } if (definedReferenceTypes.All(r => r != null)) { break; } } } }
public static XAttribute A(string attributeName, string value) { return(x.Attribute(attributeName, value)); }
private void UpdateXmlReferenceFromLastSection(XElement xml, XElement lastSectionXml, bool isHeader) { if ((xml == null) || (lastSectionXml == null)) { return; } var references = xml.Elements(XName.Get(isHeader ? "headerReference" : "footerReference", w.NamespaceName)); var lastSectionReferences = lastSectionXml.Elements(XName.Get(isHeader ? "headerReference" : "footerReference", w.NamespaceName)); // First, Even, Odd(default) var definedReferenceTypes = new List <XElement>() { null, null, null }; foreach (var r in references) { var rType = r.Attribute(w + "type").Value; switch (rType) { case "first": definedReferenceTypes[0] = r; break; case "even": definedReferenceTypes[1] = r; break; default: definedReferenceTypes[2] = r; break; } } // Current section do not have a reference, copy the one from last section if available. if (definedReferenceTypes[0] == null) { var lastSectionFirst = lastSectionReferences.FirstOrDefault(x => x.Attribute(w + "type").Value == "first"); if (lastSectionFirst != null) { xml.Add(lastSectionFirst); } } if (definedReferenceTypes[1] == null) { var lastSectionEven = lastSectionReferences.FirstOrDefault(x => x.Attribute(w + "type").Value == "even"); if (lastSectionEven != null) { xml.Add(lastSectionEven); } } if (definedReferenceTypes[2] == null) { var lastSectionDefault = lastSectionReferences.FirstOrDefault(x => x.Attribute(w + "type").Value == "default"); if (lastSectionDefault != null) { xml.Add(lastSectionDefault); } } }
public static XAttribute A(string attributeName, string value) => x.Attribute(attributeName, value);