StructType GetStruct(MetaDataTypeDefinition d, SymbolTable bindings, string path) { StructType t = new StructType(new InputElement(d.Name), bindings); bindings.Add(t.Name, t); return((StructType)FillIn(t, d, path)); }
InterfaceType GetInterface(MetaDataTypeDefinition d, SymbolTable bindings, string path) { InterfaceType t = new InterfaceType(new InputElement(d.Name), bindings); bindings.Add(t.Name, t); return((InterfaceType)FillIn(t, d, path)); }
ClassType GetClass(MetaDataTypeDefinition d, SymbolTable bindings, string path) { ClassType t = new ClassType(new InputElement(d.Name), bindings); bindings.Add(t.Name, t); return(FillIn(t, d, path)); }
EnumType GetEnum(MetaDataTypeDefinition d, SymbolTable bindings, string path) { EnumType t = new EnumType(new InputElement(d.Name), bindings); bindings.Add(t.Name, t); MetaDataField v = null; foreach (MetaDataField x in d.Fields) { if (x.Name == "value__") { v = x; break; } } t.baseType = GetType(v.Signature.FieldType, path); foreach (MetaDataField x in d.Fields) { if (x != v) { EnumMember e = t.AddEnumMember(new InputElement(x.Name), msg); e.Type = t; e.value = x.DefaultValue; } } t.Modifiers = GetTypeModifiers(d); return(t); }
stringList GetTypeModifiers(MetaDataTypeDefinition d) { stringList mods = new stringList(); switch ((int)d.Flags & (int)(TypeAttributes.VisibilityMask)) { case (int)TypeAttributes.NotPublic: case (int)TypeAttributes.NestedPrivate: mods.Add("private"); break; case (int)TypeAttributes.NestedFamORAssem: mods.Add("protected"); mods.Add("internal"); break; case (int)TypeAttributes.NestedAssembly: mods.Add("internal"); break; case (int)TypeAttributes.NestedFamily: mods.Add("protected"); break; case (int)TypeAttributes.Public: case (int)TypeAttributes.NestedPublic: mods.Add("public"); break; } if (((int)d.Flags & (int)TypeAttributes.Sealed) != 0) { mods.Add("sealed"); } if (((int)d.Flags & (int)TypeAttributes.Abstract) != 0) { mods.Add("abstract"); } return(mods); }
// 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 static void Main(String[] args) { Console.WriteLine("MkMsil:"); ArrayList streams = new ArrayList(); foreach (string arg in args) { streams.Add(new MetaDataResolver.LoadedStream(arg, Path.GetFullPath(arg), new FileStream(arg, FileMode.Open, FileAccess.Read, FileShare.Read))); } Console.WriteLine("-----------------------------------------------------------------"); MetaDataResolver resolver = new MetaDataResolver(streams, false, false, false); Console.WriteLine("-----------------------------------------------------------------"); MetaDataResolver.ResolveCustomAttributes(new MetaDataResolver[] { resolver }); Console.WriteLine("-----------------------------------------------------------------"); MetaDataTypeDefinition shellCommandAttribute = resolver.ResolveName("Microsoft.Singularity.Shell.ShellCommandAttribute"); Console.WriteLine("{0}", shellCommandAttribute); Console.WriteLine("-----------------------------------------------------------------"); #if DONT foreach (MetaData metadata in resolver.MetaDataList) { DumpMetaData(metadata); } #endif foreach (MetaData metadata in resolver.MetaDataList) { foreach (MetaDataTypeDefinition type in metadata.TypeDefs) { foreach (MetaDataMethod method in type.Methods) { MetaDataCustomAttribute attribute = MethodFindAttribute(method, shellCommandAttribute); if (attribute != null) { Console.WriteLine("new ShellCommand(\"{0}\", \"{1}\", new Command({2})),", attribute.FixedArgs[0], attribute.FixedArgs[1], method.Name); } } } } }
DelegateType GetDelegate(MetaDataTypeDefinition d, SymbolTable bindings, string path) { DelegateType t = new DelegateType(new InputElement(d.Name), bindings); bindings.Add(t.Name, t); FillIn(t, d, path); MethodSuite m = t.members["Invoke"] as MethodSuite; if (m != null && m.Count == 1) { t.invoke = m[0]; } return(t); }
public static MetaDataCustomAttribute MethodFindAttribute(MetaDataMethod method, MetaDataTypeDefinition type) { if (method.CustomAttributes != null) { foreach (MetaDataCustomAttribute attribute in method.CustomAttributes) { if (attribute.TypeDefOrRef == type) { return(attribute); } } } return(null); }
// parse utility function to ensure that a type's inheritance matches the // inheritance specified in the TokenDefinition public bool MatchInheritance(string derivesFromClass, MetaDataTypeDefinition type) { //Console.WriteLine("derives=({0}), type = {1}", // derivesFromClass, // type.Extends == null ? null: ((MetaDataTypeReference)type.Extends).FullName); // // if (derivesFromClass != null) { // if (type.Extends == null || // ((MetaDataTypeReference)type.Extends).FullName != // derivesFromClass) { // return false; // } // } // return(true); }
Symbol GetSymbol(MetaDataTypeDefinition d, string path) { SymbolTable bindings; if (d.IsNestedType) { bindings = ((ClassType)ResolveTypeRef(d.EnclosingClass, path)).members; } else { bindings = GetNameSpace(d.Namespace).members; } Type t = bindings[d.Name] as Type; if (t != null) { return(t); } switch ((int)d.Flags & (int)TypeAttributes.ClassSemanticsMask) { case (int)TypeAttributes.Class: switch (GetBaseClassName(d.Extends)) { case "System.Enum": t = GetEnum(d, bindings, path); break; case "System.Delegate": case "System.MulticastDelegate": t = GetDelegate(d, bindings, path); break; case "System.ValueType": t = GetStruct(d, bindings, path); break; default: t = GetClass(d, bindings, path); break; } break; case (int)TypeAttributes.Interface: t = GetInterface(d, bindings, path); break; default: Debug.Fail("unknown metadata type"); break; } t.module = path.ToLower(); return(t); }
// this does the processing of each class-level decoration on a type, as // described in rules.classAttributes private void ProcessClassAttributes(MetaDataTypeDefinition type, ClassDefinition[] rules, XmlNode parent) { if (type.CustomAttributes == null) { return; } foreach (MetaDataCustomAttribute attrib in type.CustomAttributes) { foreach (ClassDefinition rule in rules) { if (attrib.Name == rule.attribute) { XmlNode node = CreateNode(attrib, rule); parent.AppendChild(node); } } } }
public static bool HasCustomAttributes(MetaDataTypeDefinition type) { if (type.CustomAttributes != null) { return(true); } #if DONT_DO_INTERFACES if (type.Interfaces != null && type.Interfaces.Length != 0) { Console.WriteLine(" interfaces:"); foreach (MetaDataObject iface in type.Interfaces) { Console.WriteLine(" {0}", iface); } } #endif #if DONT_DO_FIELDS if (type.Fields != null && type.Fields.Length != 0) { Console.WriteLine(" fields:"); foreach (MetaDataField field in type.Fields) { Console.WriteLine(" {0}", field.Name); } } #endif if (type.Methods != null && type.Methods.Length != 0) { foreach (MetaDataMethod method in type.Methods) { if (method.CustomAttributes != null) { return(true); } } } return(false); }
private XmlNode GetEndpointHierarchy(string nodeName, string endpointType) { XmlNode node = AddElement(null, nodeName); MetaDataTypeDefinition epType = resolver.ResolveName(endpointType); XmlNode oldChild = null; XmlNode newChild = null; while (epType.FullName != "Microsoft.Singularity.Channels.Endpoint") { newChild = manifest.CreateNode(XmlNodeType.Element, "inherit", ""); AddAttribute(newChild, "name", epType.FullName); if (oldChild == null) { node.AppendChild(newChild); } else { node.InsertBefore(newChild, oldChild); } oldChild = newChild; string nextName; if (epType.Extends is MetaDataTypeReference) { nextName = ((MetaDataTypeReference)epType.Extends).FullName; if (nextName == "Exp" || nextName == "Imp") { MetaDataTypeReference mdtr = (MetaDataTypeReference)epType.Extends; nextName = ((MetaDataTypeReference)mdtr.ResolutionScope).FullName + "." + nextName; } } else if (epType.Extends is MetaDataTypeDefinition) { nextName = ((MetaDataTypeDefinition)epType.Extends).FullName; } else { return(node); } epType = resolver.ResolveName(nextName); } newChild = manifest.CreateNode(XmlNodeType.Element, "inherit", ""); AddAttribute(newChild, "name", epType.FullName); if (oldChild == null) { node.AppendChild(newChild); } else { node.InsertBefore(newChild, oldChild); oldChild = newChild; } return(node); }
// Endpoints are special in a lot of ways, and require a special method public XmlNode CreateEndpointNode(MetaDataCustomAttribute data, EndpointDefinition rule, int index) { // assume that the constructor to an endpoint always takes one argument, // and that the argument looks like this: // "<discard*> contractname+Exp*,AssemblyName, Version=foo, // Culture=bar, PublicKeyToken=fbar" // we'll parse this to get all the attributes of the top-level tag, and // then parse field that is being decorated to get the rest of the // information we need. // get the type of the field that is decorated: MetaDataObject t = (MetaDataObject) ((MetaDataField)data.Parent).Signature.FieldType.ClassObject; // split the field to get the parts we need string typeName = t.FullName; typeName = typeName.Replace("<", ","); typeName = typeName.Replace(">", ""); typeName = typeName.Replace("+", ","); string [] nameParts = typeName.Split(','); string contractName = nameParts[1]; string impName = contractName + ".Imp"; string expName = contractName + ".Exp"; string stateName = contractName + "." + nameParts[4]; XmlNode impNode = GetEndpointHierarchy("imp", impName); XmlNode expNode = GetEndpointHierarchy("exp", expName); MetaDataTypeDefinition r1 = resolver.ResolveName(impName); MetaDataTypeDefinition r2 = resolver.ResolveName(expName); MetaDataTypeDefinition r3 = resolver.ResolveName(stateName); string startState = ""; for (int i = 0; i < r3.Fields.Length; i++) { if (r3.Fields[i].Name == "Value") { startState = r3.Fields[0].DefaultValue.ToString(); break; } } XmlNode node = manifest.CreateNode(XmlNodeType.Element, rule.xmlTagName, ""); node.AppendChild(impNode); node.AppendChild(expNode); AddAttribute(node, "id", index.ToString()); if (startState != "") { AddAttribute(node, "startStateId", startState); } // Contract name comes from either the attribute argument // or the TRef type depending on the endpoint kind rule.AddContractNameAttribute(this, node, data, contractName); // add an attribute for each constructor argument if there is one // This should only be true for input/ouput pipes if (rule.constructorFields != null && rule.constructorFields.Length != 0) { if (data.FixedArgs.Length != 0) { for (int i = 0; i < data.FixedArgs.Length; i++) { if (rule.constructorFields[i] != null) { string name = rule.constructorFields[i]; if (data.FixedArgs[i] == null) { AddAttribute(node, name, ""); } else { string value = data.FixedArgs[i].ToString(); AddAttribute(node, name, value); } } else { Console.WriteLine(" fixed=({0}), no matching constructor?", data.FixedArgs[i] == null? null : data.FixedArgs[i].ToString()); } } } } return(node); }
ClassType FillIn(ClassType t, MetaDataTypeDefinition d, string path) { foreach (MetaDataTypeDefinition x in d.NestedClasses) { GetSymbol(x, path); } foreach (MetaDataField x in d.Fields) { Field f = t.AddField(new InputElement(x.Name), msg); f.Modifiers = GetFieldModifiers(x); f.Type = GetType(x.Signature.FieldType, path); } foreach (MetaDataMethod x in d.Methods) { if (x.Name == "get_Item" || x.Name == "set_Item" || d.FullName == "System.String" && x.Name == "get_Chars") { GetMethod(t, x.Name, x, path); // indexer } else if (x.Name.StartsWith("get_") || x.Name.StartsWith("set_")) { Property p; string name = x.Name.Substring(4); if (t.members.Contains(name)) { p = (Property)t.members[name]; } else { p = t.AddProperty(new InputElement(name), msg); } p.Modifiers = GetMethodModifiers(x); Method m; if (x.Name.StartsWith("get_")) { m = p.AddGet(new InputElement(name)); m.Type = GetType(x.Signature.ReturnType, path); } else { m = p.AddSet(new InputElement(name)); p.Type = GetType(x.Signature.Parameters[0].Type, path); m.Type = global.Types.Void; } m.Modifiers = p.Modifiers; } else if (x.Name == ".ctor") { GetMethod(t.AddConstructor(new InputElement(t.Name), msg), x, path); } else if (x.Name == ".cctor") { Constructor m = new Constructor(new InputElement(t.Name), t.members); GetMethod(m, x, path); } else { GetMethod(t, x.Name, x, path); } } t.Modifiers = GetTypeModifiers(d); t.baseClass = (ClassType)ResolveTypeRef(d.Extends, path); t.enclosingType = (ClassType)ResolveTypeRef(d.EnclosingClass, path); foreach (MetaDataObject x in d.Interfaces) { InterfaceType f = ResolveTypeRef(x, path) as InterfaceType; if (f != null) { t.interfaces.Add(f); } } return(t); }
// this does the processing of each field-level decoration on a type, // according to rules.fieldAttributes private void ProcessFieldAttributes(MetaDataTypeDefinition type, FieldDefinition[] rules, XmlNode parent) { int endpointIndex = 0; int intParameterIndex = 0; int stringParameterIndex = 0; int stringArrayParameterIndex = 0; int boolParameterIndex = 0; foreach (MetaDataField field in type.Fields) { if (field.CustomAttributes == null) { continue; } foreach (MetaDataCustomAttribute attrib in field.CustomAttributes) { foreach (FieldDefinition rule in rules) { if (attrib.Name == rule.attribute) { // type check it if (MatchFieldType(rule, field)) { // custom step if Endpoint: XmlNode node; EndpointDefinition edrule = rule as EndpointDefinition; if (edrule != null) { node = CreateEndpointNode(attrib, edrule, endpointIndex++); } else if (rule is ParameterDefinition) { int index; if (rule.matchClassType == "I8") { index = intParameterIndex++; } else if (rule.matchClassType == "STRING") { index = stringParameterIndex++; } else if (rule.matchClassType == "BOOLEAN") { index = boolParameterIndex++; } else if (rule.matchClassType == "SZARRAY") { index = stringArrayParameterIndex++; } else { index = 999; } node = CreateNodeIndexed(attrib, rule, index); } else { node = CreateNode(attrib, rule); } if (node != null) { XmlNode group = parent[rule.xmlGroup]; if (group == null) { group = AddElement(parent, rule.xmlGroup); } group.AppendChild(node); } } } } } } }