public AddinScanner(AddinDatabase database, AddinScanResult scanResult, IProgressStatus monitor) { this.database = database; if (!scanResult.CheckOnly) { string refName = GetType().Assembly.FullName; int i = refName.IndexOf(','); refName = "Mono.Addins.CecilReflector.Reflector, Mono.Addins.CecilReflector" + refName.Substring(i); Type t = Type.GetType(refName, false); if (t != null) { reflector = (IAssemblyReflector)Activator.CreateInstance(t); } else { reflector = new DefaultAssemblyReflector(); } if (monitor.LogLevel > 1) { monitor.Log("Using assembly reflector: " + reflector.GetType()); } reflector.Initialize(scanResult); coreAssembly = reflector.LoadAssembly(GetType().Assembly.Location); } }
public AddinScanner(AddinDatabase database, AddinScanResult scanResult, IProgressStatus monitor) { this.database = database; if (!scanResult.CheckOnly) { // If there is a local copy of the cecil reflector, use it instead of the one in the gac Type t; string asmFile = Path.Combine (Path.GetDirectoryName (GetType().Assembly.Location), "Mono.Addins.CecilReflector.dll"); if (File.Exists (asmFile)) { Assembly asm = Assembly.LoadFrom (asmFile); t = asm.GetType ("Mono.Addins.CecilReflector.Reflector"); } else { string refName = GetType().Assembly.FullName; int i = refName.IndexOf (','); refName = "Mono.Addins.CecilReflector.Reflector, Mono.Addins.CecilReflector" + refName.Substring (i); t = Type.GetType (refName, false); } if (t != null) reflector = (IAssemblyReflector) Activator.CreateInstance (t); else reflector = new DefaultAssemblyReflector (); if (monitor.LogLevel > 1) monitor.Log ("Using assembly reflector: " + reflector.GetType ()); reflector.Initialize (scanResult); coreAssembly = reflector.LoadAssembly (GetType().Assembly.Location); } }
private static HashSet <string> GetSlashdocIdsForAllVisibleTypesAndMembers(IAssemblyReflector assembly) { var ids = new HashSet <string>(); foreach (var type in assembly.Types .Where(t => ReflectionHelper.IsVisible(t))) { ids.Add(SlashdocIdentifierProvider.GetId(type)); if (type.IsEnum) { AddSlashdocIds(ReflectionHelper.GetEnumMembers(type), (x) => SlashdocIdentifierProvider.GetId(x), ids); } else { AddSlashdocIds(ReflectionHelper.GetVisibleConstructors(type), (x) => SlashdocIdentifierProvider.GetId(x), ids); AddSlashdocIds(ReflectionHelper.GetVisibleProperties(type), (x) => SlashdocIdentifierProvider.GetId(x), ids); AddSlashdocIds(ReflectionHelper.GetVisibleMethods(type), (x) => SlashdocIdentifierProvider.GetId(x), ids); AddSlashdocIds(ReflectionHelper.GetVisibleOperators(type), (x) => SlashdocIdentifierProvider.GetId(x), ids); AddSlashdocIds(ReflectionHelper.GetVisibleFields(type), (x) => SlashdocIdentifierProvider.GetId(x), ids); AddSlashdocIds(ReflectionHelper.GetVisibleEvents(type), (x) => SlashdocIdentifierProvider.GetId(x), ids); } } return(ids); }
private void WriteTypesOverviewTable(IAssemblyReflector assembly, SlashdocSummaryHtmlFormatter formatter) { WriteDescriptionTableHeader("Types"); foreach (var type in assembly.Types .Where(t => ReflectionHelper.IsVisible(t)) .OrderBy(t => _language.GetDisplayName(t))) { var displayName = _language.GetDisplayName(type); _writer.WriteStartElement("tr"); _writer.WriteStartElement("td"); _writer.WriteStartElement("a"); _writer.WriteAttributeString("href", "#" + displayName); _writer.WriteString(displayName); _writer.WriteEndElement(); // a _writer.WriteString(" " + _language.GetMetaTypeName(type)); _writer.WriteEndElement(); // td _writer.WriteStartElement("td"); var slashdocSummaryHtml = formatter.FormatSummary(LookupXmlDescription( SlashdocIdentifierProvider.GetId(type), displayName + " " + _language.GetMetaTypeName(type))); _writer.WriteRaw(slashdocSummaryHtml); _writer.WriteEndElement(); // td _writer.WriteEndElement(); // tr } WriteDescriptionTableFooter(); }
/// <summary> /// Gets an assembly reflector for a file. /// </summary> /// <returns> /// The reflector for the file. /// </returns> /// <param name='locator'> /// An assembly locator /// </param> /// <param name='path'> /// A file path /// </param> public virtual IAssemblyReflector GetReflectorForFile(IAssemblyLocator locator, string path) { if (reflector != null) { return(reflector); } // If there is a local copy of the cecil reflector, use it instead of the one in the gac Type t; string asmFile = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), "Mono.Addins.CecilReflector.dll"); if (File.Exists(asmFile)) { Assembly asm = Assembly.LoadFrom(asmFile); t = asm.GetType("Mono.Addins.CecilReflector.Reflector"); } else { string refName = GetType().Assembly.FullName; int i = refName.IndexOf(','); refName = "Mono.Addins.CecilReflector.Reflector, Mono.Addins.CecilReflector" + refName.Substring(i); t = Type.GetType(refName, false); } if (t != null) { reflector = (IAssemblyReflector)Activator.CreateInstance(t); } else { reflector = new DefaultAssemblyReflector(); } reflector.Initialize(locator); return(reflector); }
public SlashdocSummaryHtmlFormatter(IAssemblyReflector assemblyReflector, ILanguageSignatureProvider language) { if (assemblyReflector == null) throw new ArgumentNullException("assemblyReflector"); if (language == null) throw new ArgumentNullException("language"); _assemblyReflector = assemblyReflector; _language = language; }
public SlashdocSummaryHtmlFormatter(IAssemblyReflector assemblyReflector, ILanguageSignatureProvider language) { if (assemblyReflector == null) throw new ArgumentNullException("assemblyReflector"); if (language == null) throw new ArgumentNullException("language"); _assemblyReflector = assemblyReflector; _language = language; }
public void DescribeAssembly(IAssemblyReflector assembly) { var formatter = new SlashdocSummaryHtmlFormatter(assembly, _language); var title = string.Format(CultureInfo.InvariantCulture, "{0} public API reference", assembly.SimpleName); WriteTextElement("h1", title); WriteTypesOverviewTable(assembly, formatter); foreach (var type in assembly.Types .Where(t => ReflectionHelper.IsVisible(t)) .OrderBy(t => _language.GetShortDisplayName(t))) { DescribeType(type, formatter); } }
/// <summary> /// Write a filtered slashdoc file with the public API only, for use with IntelliSense. /// </summary> public static void WritePublicApiSlashdoc(IAssemblyReflector assemblyReflector, Stream slashdocStream, string fileName) { var publicSlashdocIds = GetSlashdocIdsForAllVisibleTypesAndMembers(assemblyReflector); using (var reader = new SlashdocReader(slashdocStream)) using (var writer = XmlWriter.Create(fileName)) { writer.WriteStartElement("doc"); reader.FoundAssemblyName += (x) => { writer.WriteStartElement("assembly"); writer.WriteStartElement("name"); writer.WriteString(x); writer.WriteEndElement(); // name writer.WriteEndElement(); // assembly }; int memberCount = 0; reader.FoundMember += (x) => { if (publicSlashdocIds.Contains(x.Key)) { if (memberCount == 0) { writer.WriteStartElement("members"); } memberCount++; writer.WriteStartElement("member"); writer.WriteAttributeString("name", x.Key); writer.WriteRaw(x.Value); writer.WriteEndElement(); // member } }; reader.Parse(); } }
/// <summary> /// Gets an assembly reflector for a file. /// </summary> /// <returns> /// The reflector for the file. /// </returns> /// <param name='locator'> /// An assembly locator /// </param> /// <param name='path'> /// A file path /// </param> public virtual IAssemblyReflector GetReflectorForFile (IAssemblyLocator locator, string path) { if (reflector != null) return reflector; // If there is a local copy of the cecil reflector, use it instead of the one in the gac Type t; string asmFile = Path.Combine (Path.GetDirectoryName (GetType().Assembly.Location), "Mono.Addins.CecilReflector.dll"); if (File.Exists (asmFile)) { Assembly asm = Assembly.LoadFrom (asmFile); t = asm.GetType ("Mono.Addins.CecilReflector.Reflector"); } else { string refName = GetType().Assembly.FullName; int i = refName.IndexOf (','); refName = "Mono.Addins.CecilReflector.Reflector, Mono.Addins.CecilReflector" + refName.Substring (i); t = Type.GetType (refName, false); } if (t != null) reflector = (IAssemblyReflector) Activator.CreateInstance (t); else reflector = new DefaultAssemblyReflector (); reflector.Initialize (locator); return reflector; }
bool ScanDescription(IProgressStatus monitor, IAssemblyReflector reflector, AddinDescription config, object rootAssembly, AddinScanResult scanResult) { // First of all scan the main module ArrayList assemblies = new ArrayList (); try { string rootAsmFile = null; if (rootAssembly != null) { ScanAssemblyAddinHeaders (reflector, config, rootAssembly, scanResult); ScanAssemblyImports (reflector, config.MainModule, rootAssembly); assemblies.Add (rootAssembly); rootAsmFile = Path.GetFileName (config.AddinFile); } // The assembly list may be modified while scanning the headears, so // we use a for loop instead of a foreach for (int n=0; n<config.MainModule.Assemblies.Count; n++) { string s = config.MainModule.Assemblies [n]; string asmFile = Path.GetFullPath (Path.Combine (config.BasePath, s)); scanResult.AddPathToIgnore (asmFile); if (s == rootAsmFile || config.MainModule.IgnorePaths.Contains (s)) continue; object asm = reflector.LoadAssembly (asmFile); assemblies.Add (asm); ScanAssemblyAddinHeaders (reflector, config, asm, scanResult); ScanAssemblyImports (reflector, config.MainModule, asm); } // Add all data files to the ignore file list. It avoids scanning assemblies // which are included as 'data' in an add-in. foreach (string df in config.MainModule.DataFiles) { string file = Path.Combine (config.BasePath, df); scanResult.AddPathToIgnore (Path.GetFullPath (file)); } foreach (string df in config.MainModule.IgnorePaths) { string path = Path.Combine (config.BasePath, df); scanResult.AddPathToIgnore (Path.GetFullPath (path)); } // The add-in id and version must be already assigned at this point // Clean host data from the index. New data will be added. if (scanResult.HostIndex != null) scanResult.HostIndex.RemoveHostData (config.AddinId, config.AddinFile); foreach (object asm in assemblies) ScanAssemblyContents (reflector, config, config.MainModule, asm, scanResult); } catch (Exception ex) { ReportReflectionException (monitor, ex, config, scanResult); return false; } // Extension node types may have child nodes declared as attributes. Find them. Hashtable internalNodeSets = new Hashtable (); ArrayList setsCopy = new ArrayList (); setsCopy.AddRange (config.ExtensionNodeSets); foreach (ExtensionNodeSet eset in setsCopy) ScanNodeSet (reflector, config, eset, assemblies, internalNodeSets); foreach (ExtensionPoint ep in config.ExtensionPoints) { ScanNodeSet (reflector, config, ep.NodeSet, assemblies, internalNodeSets); } // Now scan all modules if (!config.IsRoot) { foreach (ModuleDescription mod in config.OptionalModules) { try { assemblies.Clear (); for (int n=0; n<mod.Assemblies.Count; n++) { string s = mod.Assemblies [n]; if (mod.IgnorePaths.Contains (s)) continue; string asmFile = Path.Combine (config.BasePath, s); object asm = reflector.LoadAssembly (asmFile); assemblies.Add (asm); scanResult.AddPathToIgnore (Path.GetFullPath (asmFile)); ScanAssemblyImports (reflector, mod, asm); } // Add all data files to the ignore file list. It avoids scanning assemblies // which are included as 'data' in an add-in. foreach (string df in mod.DataFiles) { string file = Path.Combine (config.BasePath, df); scanResult.AddPathToIgnore (Path.GetFullPath (file)); } foreach (string df in mod.IgnorePaths) { string path = Path.Combine (config.BasePath, df); scanResult.AddPathToIgnore (Path.GetFullPath (path)); } foreach (object asm in assemblies) ScanAssemblyContents (reflector, config, mod, asm, scanResult); } catch (Exception ex) { ReportReflectionException (monitor, ex, config, scanResult); } } } config.StoreFileInfo (); return true; }
void ScanAssemblyImports(IAssemblyReflector reflector, ModuleDescription module, object asm) { object[] atts = reflector.GetCustomAttributes (asm, typeof(ImportAddinAssemblyAttribute), false); foreach (ImportAddinAssemblyAttribute import in atts) { if (!string.IsNullOrEmpty (import.FilePath)) { module.Assemblies.Add (import.FilePath); if (!import.Scan) module.IgnorePaths.Add (import.FilePath); } } atts = reflector.GetCustomAttributes (asm, typeof(ImportAddinFileAttribute), false); foreach (ImportAddinFileAttribute import in atts) { if (!string.IsNullOrEmpty (import.FilePath)) module.DataFiles.Add (import.FilePath); } }
void ScanAssemblyContents(IAssemblyReflector reflector, AddinDescription config, ModuleDescription module, object asm, AddinScanResult scanResult) { bool isMainModule = module == config.MainModule; // Get dependencies object[] deps = reflector.GetCustomAttributes (asm, typeof(AddinDependencyAttribute), false); foreach (AddinDependencyAttribute dep in deps) { AddinDependency adep = new AddinDependency (); adep.AddinId = dep.Id; adep.Version = dep.Version; module.Dependencies.Add (adep); } if (isMainModule) { // Get properties object[] props = reflector.GetCustomAttributes (asm, typeof(AddinPropertyAttribute), false); foreach (AddinPropertyAttribute prop in props) config.Properties.SetPropertyValue (prop.Name, prop.Value, prop.Locale); // Get extension points object[] extPoints = reflector.GetCustomAttributes (asm, typeof(ExtensionPointAttribute), false); foreach (ExtensionPointAttribute ext in extPoints) { ExtensionPoint ep = config.AddExtensionPoint (ext.Path); ep.Description = ext.Description; ep.Name = ext.Name; ExtensionNodeType nt = ep.AddExtensionNode (ext.NodeName, ext.NodeTypeName); nt.ExtensionAttributeTypeName = ext.ExtensionAttributeTypeName; } } // Look for extension nodes declared using assembly attributes foreach (CustomAttribute att in reflector.GetRawCustomAttributes (asm, typeof(CustomExtensionAttribute), true)) AddCustomAttributeExtension (module, att, "Type"); // Get extensions or extension points applied to types foreach (object t in reflector.GetAssemblyTypes (asm)) { string typeFullName = reflector.GetTypeFullName (t); // Look for extensions object[] extensionAtts = reflector.GetCustomAttributes (t, typeof(ExtensionAttribute), false); if (extensionAtts.Length > 0) { Dictionary<string,ExtensionNodeDescription> nodes = new Dictionary<string, ExtensionNodeDescription> (); ExtensionNodeDescription uniqueNode = null; foreach (ExtensionAttribute eatt in extensionAtts) { string path; string nodeName = eatt.NodeName; if (eatt.TypeName.Length > 0) { path = "$" + eatt.TypeName; } else if (eatt.Path.Length == 0) { path = GetBaseTypeNameList (reflector, t); if (path == "$") { // The type does not implement any interface and has no superclass. // Will be reported later as an error. path = "$" + typeFullName; } } else { path = eatt.Path; } ExtensionNodeDescription elem = module.AddExtensionNode (path, nodeName); nodes [path] = elem; uniqueNode = elem; if (eatt.Id.Length > 0) { elem.SetAttribute ("id", eatt.Id); elem.SetAttribute ("type", typeFullName); } else { elem.SetAttribute ("id", typeFullName); } if (eatt.InsertAfter.Length > 0) elem.SetAttribute ("insertafter", eatt.InsertAfter); if (eatt.InsertBefore.Length > 0) elem.SetAttribute ("insertbefore", eatt.InsertBefore); } // Get the node attributes foreach (ExtensionAttributeAttribute eat in reflector.GetCustomAttributes (t, typeof(ExtensionAttributeAttribute), false)) { ExtensionNodeDescription node; if (!string.IsNullOrEmpty (eat.Path)) nodes.TryGetValue (eat.Path, out node); else if (eat.TypeName.Length > 0) nodes.TryGetValue ("$" + eat.TypeName, out node); else { if (nodes.Count > 1) throw new Exception ("Missing type or extension path value in ExtensionAttribute for type '" + typeFullName + "'."); node = uniqueNode; } if (node == null) throw new Exception ("Invalid type or path value in ExtensionAttribute for type '" + typeFullName + "'."); node.SetAttribute (eat.Name ?? string.Empty, eat.Value ?? string.Empty); } } else { // Look for extension points extensionAtts = reflector.GetCustomAttributes (t, typeof(TypeExtensionPointAttribute), false); if (extensionAtts.Length > 0 && isMainModule) { foreach (TypeExtensionPointAttribute epa in extensionAtts) { ExtensionPoint ep; ExtensionNodeType nt = new ExtensionNodeType (); if (epa.Path.Length > 0) { ep = config.AddExtensionPoint (epa.Path); } else { ep = config.AddExtensionPoint (GetDefaultTypeExtensionPath (config, typeFullName)); nt.ObjectTypeName = typeFullName; } nt.Id = epa.NodeName; nt.TypeName = epa.NodeTypeName; nt.ExtensionAttributeTypeName = epa.ExtensionAttributeTypeName; ep.NodeSet.NodeTypes.Add (nt); ep.Description = epa.Description; ep.Name = epa.Name; ep.RootAddin = config.AddinId; ep.SetExtensionsAddinId (config.AddinId); } } else { // Look for custom extension attribtues foreach (CustomAttribute att in reflector.GetRawCustomAttributes (t, typeof(CustomExtensionAttribute), false)) { ExtensionNodeDescription elem = AddCustomAttributeExtension (module, att, "Type"); elem.SetAttribute ("type", typeFullName); if (string.IsNullOrEmpty (elem.GetAttribute ("id"))) elem.SetAttribute ("id", typeFullName); } } } } }
void ScanAssemblyAddinHeaders(IAssemblyReflector reflector, AddinDescription config, object asm, AddinScanResult scanResult) { // Get basic add-in information AddinAttribute att = (AddinAttribute) reflector.GetCustomAttribute (asm, typeof(AddinAttribute), false); if (att != null) { if (att.Id.Length > 0) config.LocalId = att.Id; if (att.Version.Length > 0) config.Version = att.Version; if (att.Namespace.Length > 0) config.Namespace = att.Namespace; if (att.Category.Length > 0) config.Category = att.Category; if (att.CompatVersion.Length > 0) config.CompatVersion = att.CompatVersion; if (att.Url.Length > 0) config.Url = att.Url; config.IsRoot = att is AddinRootAttribute; config.EnabledByDefault = att.EnabledByDefault; config.Flags = att.Flags; } // Author attributes object[] atts = reflector.GetCustomAttributes (asm, typeof(AddinAuthorAttribute), false); foreach (AddinAuthorAttribute author in atts) { if (config.Author.Length == 0) config.Author = author.Name; else config.Author += ", " + author.Name; } // Name atts = reflector.GetCustomAttributes (asm, typeof(AddinNameAttribute), false); foreach (AddinNameAttribute at in atts) { if (string.IsNullOrEmpty (at.Locale)) config.Name = at.Name; else config.Properties.SetPropertyValue ("Name", at.Name, at.Locale); } // Description object catt = reflector.GetCustomAttribute (asm, typeof(AssemblyDescriptionAttribute), false); if (catt != null && config.Description.Length == 0) config.Description = ((AssemblyDescriptionAttribute)catt).Description; atts = reflector.GetCustomAttributes (asm, typeof(AddinDescriptionAttribute), false); foreach (AddinDescriptionAttribute at in atts) { if (string.IsNullOrEmpty (at.Locale)) config.Description = at.Description; else config.Properties.SetPropertyValue ("Description", at.Description, at.Locale); } // Copyright catt = reflector.GetCustomAttribute (asm, typeof(AssemblyCopyrightAttribute), false); if (catt != null && config.Copyright.Length == 0) config.Copyright = ((AssemblyCopyrightAttribute)catt).Copyright; // Localizer AddinLocalizerGettextAttribute locat = (AddinLocalizerGettextAttribute) reflector.GetCustomAttribute (asm, typeof(AddinLocalizerGettextAttribute), false); if (locat != null) { ExtensionNodeDescription node = new ExtensionNodeDescription (); if (!string.IsNullOrEmpty (locat.Catalog)) node.SetAttribute ("catalog", locat.Catalog); if (!string.IsNullOrEmpty (locat.Location)) node.SetAttribute ("location", locat.Catalog); config.Localizer = node; } // Optional modules atts = reflector.GetCustomAttributes (asm, typeof(AddinModuleAttribute), false); foreach (AddinModuleAttribute mod in atts) { if (mod.AssemblyFile.Length > 0) { ModuleDescription module = new ModuleDescription (); module.Assemblies.Add (mod.AssemblyFile); config.OptionalModules.Add (module); } } }
string GetBaseTypeNameList(IAssemblyReflector reflector, object type) { StringBuilder sb = new StringBuilder ("$"); foreach (string tn in reflector.GetBaseTypeFullNameList (type)) sb.Append (tn).Append (','); if (sb.Length > 0) sb.Remove (sb.Length - 1, 1); return sb.ToString (); }
object FindAddinType(IAssemblyReflector reflector, string typeName, ArrayList assemblies) { // Look in the current assembly object etype = reflector.GetType (coreAssemblies [reflector], typeName); if (etype != null) return etype; // Look in referenced assemblies foreach (object asm in assemblies) { etype = reflector.GetType (asm, typeName); if (etype != null) return etype; } Hashtable visited = new Hashtable (); // Look in indirectly referenced assemblies foreach (object asm in assemblies) { foreach (object aref in reflector.GetAssemblyReferences (asm)) { if (visited.Contains (aref)) continue; visited.Add (aref, aref); object rasm = reflector.LoadAssemblyFromReference (aref); if (rasm != null) { etype = reflector.GetType (rasm, typeName); if (etype != null) return etype; } } } return null; }
void ScanNodeType(IAssemblyReflector reflector, AddinDescription config, ExtensionNodeType nt, ArrayList assemblies, Hashtable internalNodeSets) { if (nt.TypeName.Length == 0) nt.TypeName = "Mono.Addins.TypeExtensionNode"; object ntype = FindAddinType (reflector, nt.TypeName, assemblies); if (ntype == null) return; // Add type information declared with attributes in the code ExtensionNodeAttribute nodeAtt = (ExtensionNodeAttribute) reflector.GetCustomAttribute (ntype, typeof(ExtensionNodeAttribute), true); if (nodeAtt != null) { if (nt.Id.Length == 0 && nodeAtt.NodeName.Length > 0) nt.Id = nodeAtt.NodeName; if (nt.Description.Length == 0 && nodeAtt.Description.Length > 0) nt.Description = nodeAtt.Description; if (nt.ExtensionAttributeTypeName.Length == 0 && nodeAtt.ExtensionAttributeTypeName.Length > 0) nt.ExtensionAttributeTypeName = nodeAtt.ExtensionAttributeTypeName; } else { // Use the node type name as default name if (nt.Id.Length == 0) nt.Id = reflector.GetTypeName (ntype); } // Add information about attributes object[] fieldAtts = reflector.GetCustomAttributes (ntype, typeof(NodeAttributeAttribute), true); foreach (NodeAttributeAttribute fatt in fieldAtts) { NodeTypeAttribute natt = new NodeTypeAttribute (); natt.Name = fatt.Name; natt.Required = fatt.Required; if (fatt.TypeName != null) natt.Type = fatt.TypeName; if (fatt.Description.Length > 0) natt.Description = fatt.Description; nt.Attributes.Add (natt); } // Check if the type has NodeAttribute attributes applied to fields. foreach (object field in reflector.GetFields (ntype)) { NodeAttributeAttribute fatt = (NodeAttributeAttribute) reflector.GetCustomAttribute (field, typeof(NodeAttributeAttribute), false); if (fatt != null) { NodeTypeAttribute natt = new NodeTypeAttribute (); if (fatt.Name.Length > 0) natt.Name = fatt.Name; else natt.Name = reflector.GetFieldName (field); if (fatt.Description.Length > 0) natt.Description = fatt.Description; natt.Type = reflector.GetFieldTypeFullName (field); natt.Required = fatt.Required; nt.Attributes.Add (natt); } } // Check if the extension type allows children by looking for [ExtensionNodeChild] attributes. // First of all, look in the internalNodeSets hashtable, which is being used as cache string childSet = (string) internalNodeSets [nt.TypeName]; if (childSet == null) { object[] ats = reflector.GetCustomAttributes (ntype, typeof(ExtensionNodeChildAttribute), true); if (ats.Length > 0) { // Create a new node set for this type. It is necessary to create a new node set // instead of just adding child ExtensionNodeType objects to the this node type // because child types references can be recursive. ExtensionNodeSet internalSet = new ExtensionNodeSet (); internalSet.Id = reflector.GetTypeName (ntype) + "_" + Guid.NewGuid().ToString (); foreach (ExtensionNodeChildAttribute at in ats) { ExtensionNodeType internalType = new ExtensionNodeType (); internalType.Id = at.NodeName; internalType.TypeName = at.ExtensionNodeTypeName; internalSet.NodeTypes.Add (internalType); } config.ExtensionNodeSets.Add (internalSet); nt.NodeSets.Add (internalSet.Id); // Register the new set in a hashtable, to allow recursive references to the // same internal set. internalNodeSets [nt.TypeName] = internalSet.Id; internalNodeSets [reflector.GetTypeAssemblyQualifiedName (ntype)] = internalSet.Id; ScanNodeSet (reflector, config, internalSet, assemblies, internalNodeSets); } } else { if (childSet.Length == 0) { // The extension type does not declare children. return; } // The extension type can have children. The allowed children are // defined in this extension set. nt.NodeSets.Add (childSet); return; } ScanNodeSet (reflector, config, nt, assemblies, internalNodeSets); }
void ScanNodeSet(IAssemblyReflector reflector, AddinDescription config, ExtensionNodeSet nset, ArrayList assemblies, Hashtable internalNodeSets) { foreach (ExtensionNodeType nt in nset.NodeTypes) ScanNodeType (reflector, config, nt, assemblies, internalNodeSets); }
static bool ScanEmbeddedDescription (IProgressStatus monitor, string filePath, IAssemblyReflector reflector, object asm, out AddinDescription config) { config = null; foreach (string res in reflector.GetResourceNames (asm)) { if (res.EndsWith (".addin") || res.EndsWith (".addin.xml")) { using (Stream s = reflector.GetResourceStream (asm, res)) { AddinDescription ad = AddinDescription.Read (s, Path.GetDirectoryName (filePath)); if (config != null) { if (!config.IsExtensionModel && !ad.IsExtensionModel) { // There is more than one add-in definition monitor.ReportError ("Duplicate add-in definition found in assembly: " + filePath, null); return false; } config = AddinDescription.Merge (config, ad); } else config = ad; } } } return true; }
bool ScanSubmodule (IProgressStatus monitor, ModuleDescription mod, IAssemblyReflector reflector, AddinDescription config, AddinScanResult scanResult, string assemblyName, object asm) { AddinDescription mconfig; ScanEmbeddedDescription (monitor, assemblyName, reflector, asm, out mconfig); if (mconfig != null) { if (!mconfig.IsExtensionModel) { monitor.ReportError ("Submodules can't define new add-ins: " + assemblyName, null); return false; } if (mconfig.OptionalModules.Count != 0) { monitor.ReportError ("Submodules can't define nested submodules: " + assemblyName, null); return false; } if (mconfig.ConditionTypes.Count != 0) { monitor.ReportError ("Submodules can't define condition types: " + assemblyName, null); return false; } if (mconfig.ExtensionNodeSets.Count != 0) { monitor.ReportError ("Submodules can't define extension node sets: " + assemblyName, null); return false; } if (mconfig.ExtensionPoints.Count != 0) { monitor.ReportError ("Submodules can't define extension points sets: " + assemblyName, null); return false; } mod.MergeWith (mconfig.MainModule); } ScanAssemblyContents (reflector, config, mod, asm, scanResult); return true; }