// this kicks off the processing of a type; see if it is decorated by // rules.triggers, and if so, then build an xml node and process the rest // of the rules object for this type private bool ProcessType(MetaDataTypeDefinition type, ParseRules rules, XmlNode parent, ref int categoryIndex, ref XmlNode categories) { if (type.CustomAttributes == null) { return(false); } foreach (MetaDataCustomAttribute attrib in type.CustomAttributes) { foreach (TriggerDefinition rule in rules.triggers) { if (attrib.Name == rule.attribute) { // only process this entry if the ancestry is valid if (MatchInheritance(rule.derivesFromClass, type)) { if (categoryIndex == 0) { categories = AddElement(parent, "categories"); } // create an xml node from (attrib, rule) XmlNode node = CreateNode(attrib, rule); AddAttribute(node, "id", (categoryIndex++).ToString()); if (rule.categoryName != null) { AddAttribute(node, "name", rule.categoryName); } AddAttribute(node, "class", type.FullName); // then do the rules.classDefinitions work ProcessClassAttributes(type, rules.classAttributes, node); // then do the rules.fieldDefinitions work ProcessFieldAttributes(type, rules.fieldAttributes, node); // then append this xml node to the manifest root doc if (categories == null) { Console.WriteLine(" categories is null at index {0}", categoryIndex); } else { categories.AppendChild(node); } // once we match once, we stop operating on this type return(true); } } } } return(false); }
public ParseRules(ParseRules inheritFrom, TriggerDefinition[] triggers, ClassDefinition[] classAttributes, FieldDefinition[] fieldAttributes) { this.triggers = triggers; if (inheritFrom != null) { this.classAttributes = Inherit(inheritFrom.classAttributes, classAttributes); this.fieldAttributes = Inherit(inheritFrom.fieldAttributes, fieldAttributes); } else { this.classAttributes = classAttributes; this.fieldAttributes = fieldAttributes; } }
static ManifestBuilder() { ParseRules categoryRules = new ParseRules( null, // "triggers" new TriggerDefinition[] { new TriggerDefinition("category", null, "Microsoft.Singularity.Configuration.CategoryAttribute", "Microsoft.Singularity.Configuration.CategoryDeclaration", new string [] { "name" }), }, // "class" attributes new ClassDefinition[] {}, // "field" attributes new FieldDefinition[] { // NB: the constructor fields on these are handled specially, unlike // everything else in this tool. This is indicated by the "true" // value for the last parameter to the constructor // TODO: is this correct? Should Endpoint declarations in // ConsoleCategories and Configuration be given names so that they are more // human-configurable? Will an app ever declare multiple Endpoints of // the same type and require the kernel to user to patch those identical // endpoints to different (and conflicting) apps? Could this problem be // addressed via stronger typing? new EndpointDefinition("endpoints", "extension", "Microsoft.Singularity.Configuration.ExtensionEndpointAttribute", "Microsoft.Singularity.Channels.TRef_2" + "<Microsoft.Singularity.Extending." + "ExtensionContract+Exp,Microsoft.Singularity" + ".Extending.ExtensionContract+Start>"), new ServiceEndpointDefinition("endpoints", "serviceProvider", "Microsoft.Singularity.Configuration.ServiceEndpointAttribute", "Microsoft.Singularity.Channels.TRef_2" + "<Microsoft.Singularity.Directory." + "ServiceProviderContract+Exp,Microsoft." + "Singularity.Directory.ServiceProviderContract" + "+Start>"), // TODO: - the inheritance on this is not correct new EndpointDefinition("endpoints", "endpoint", "Microsoft.Singularity.Configuration.EndpointAttribute", null), new EndpointDefinition("endpoints", "customEndpoint", "Microsoft.Singularity.Configuration.CustomEndpointAttribute", null), new EndpointDefinition("endpoints", "inputPipe", "Microsoft.Singularity.Configuration.InputEndpointAttribute", null, new string [] { "Kind" }), new EndpointDefinition("endpoints", "outputPipe", "Microsoft.Singularity.Configuration.OutputEndpointAttribute", null, new string [] { "Kind" }), new ParameterDefinition("StringParameters", "StringParameter", "Microsoft.Singularity.Configuration.StringParameterAttribute", "STRING", new string [] { "Name" }), new ParameterDefinition("LongParameters", "LongParameter", "Microsoft.Singularity.Configuration.LongParameterAttribute", "I8", new string [] { "Name" }), new ParameterDefinition("BoolParameters", "BoolParameter", "Microsoft.Singularity.Configuration.BoolParameterAttribute", "BOOLEAN", new string [] { "Name" }), new ParameterDefinition("StringArrayParameters", "StringArrayParameter", "Microsoft.Singularity.Configuration.StringArrayParameterAttribute", "SZARRAY", new string [] { "Name" }), } ); ParseRules driverCategoryRules = new ParseRules( categoryRules, // inherit "class" and "field" rules from category. // "triggers" new TriggerDefinition[] { new TriggerDefinition("category", "driver", "Microsoft.Singularity.Io.DriverCategoryAttribute", "Microsoft.Singularity.Io.DriverCategoryDeclaration"), }, // "class" attributes new ClassDefinition[] { new ClassDefinition("device", "Microsoft.Singularity.Io.SignatureAttribute", new string [] { "signature" }), new ClassDefinition("enumerates", "Microsoft.Singularity.Io.EnumeratesDeviceAttribute", new string [] { "signature" }), }, // "field" attributes new FieldDefinition[] { new FieldDefinition("dynamicHardware", "ioPortRange", "Microsoft.Singularity.Io.IoPortRangeAttribute", "Microsoft.Singularity.Io.IoPortRange", new string [] { "id" }, new string [] { "Default", "baseAddress", "Length", "rangeLength", "Shared", "shared" }), new FieldDefinition("fixedHardware", "ioPortRange", "Microsoft.Singularity.Io.IoFixedPortRangeAttribute", "Microsoft.Singularity.Io.IoPortRange", new string [] { "id" }, new string [] { "Base", "baseAddress", "Length", "rangeLength", "Shared", "shared" }, new string [] { "fixed", "true" }), new FieldDefinition("dynamicHardware", "ioIrqRange", "Microsoft.Singularity.Io.IoIrqRangeAttribute", "Microsoft.Singularity.Io.IoIrqRange", new string [] { "id" }, new string [] { "Default", "baseAddress", "Length", "rangeLength", "Shared", "shared" }, new string [] { "rangeLength", "1" }), new FieldDefinition("fixedHardware", "ioIrqRange", "Microsoft.Singularity.Io.IoFixedIrqRangeAttribute", "Microsoft.Singularity.Io.IoIrqRange", new string [] { "id" }, new string [] { "Base", "baseAddress", "Length", "rangeLength", "Shared", "shared" }, new string [] { "fixed", "true", "rangeLength", "1" }), new FieldDefinition("dynamicHardware", "ioDmaRange", "Microsoft.Singularity.Io.IoDmaRangeAttribute", "Microsoft.Singularity.Io.IoDmaRange", new string [] { "id" }, new string [] { "Default", "baseAddress", "Length", "rangeLength", "Shared", "shared" }, new string [] { "rangeLength", "1" }), new FieldDefinition("dynamicHardware", "ioMemoryRange", "Microsoft.Singularity.Io.IoMemoryRangeAttribute", "Microsoft.Singularity.Io.IoMemoryRange", new string [] { "id" }, new string [] { "Default", "baseAddress", "Length", "rangeLength", "Shared", "shared" }), new FieldDefinition("fixedHardware", "ioMemoryRange", "Microsoft.Singularity.Io.IoFixedMemoryRangeAttribute", "Microsoft.Singularity.Io.IoMemoryRange", new string [] { "id" }, new string [] { "Base", "baseAddress", "Length", "rangeLength", "Shared", "shared", "AddressBits", "addressBits", "Alignment", "alignment" }, new string [] { "fixed", "true" }), } ); ParseRules consoleCategoryRules = new ParseRules( categoryRules, // inherit "class" and "field" rules from category. // "triggers" new TriggerDefinition[] { new TriggerDefinition("category", "console", "Microsoft.Singularity.Configuration.ConsoleCategoryAttribute", "Microsoft.Singularity.Configuration.ConsoleCategoryDeclaration"), }, // "class" attributes new ClassDefinition[] { }, // "field" attributes new FieldDefinition[] { } ); rules = new ParseRules[3] { driverCategoryRules, categoryRules, consoleCategoryRules, }; }