/// <summary> /// Traverse the given assembly (located in options.Assembly) for contracts and return the contracts. /// </summary> /// <remarks> /// We use dictionary mapping special string ids that are unique to each member in an XML file to /// the contracts that that member has. /// </remarks> static IDictionary <string, XContract[]> GetContracts(Options options, DocTracker docTracker) { Contract.Requires(options != null); Contract.Requires(docTracker != null); Contract.Ensures(Contract.Result <IDictionary <string, XContract[]> >() != null); #region Establish host and load assembly Contract.Assume(options.resolvedPaths != null); var host = new CodeContractAwareHostEnvironment(options.libpaths); foreach (var p in options.resolvedPaths) { host.AddResolvedPath(p); } IModule module = host.LoadUnitFrom(options.assembly) as IModule; if (module == null || module == Dummy.Module || module == Dummy.Assembly) { Console.WriteLine("'{0}' is not a PE file containing a CLR module or assembly.", options.assembly); Environment.Exit(1); } #endregion #region Create the contracts dictionary Dictionary <string, XContract[]> contracts = new Dictionary <string, XContract[]>(StringComparer.Ordinal); //Use Ordinal compare for faster string comparison. #endregion #region Traverse module and extract contracts var contractsVisitor = new ContractVisitor(host, contracts, options, docTracker); var traverser = new ContractTraverser(host); traverser.PreorderVisitor = contractsVisitor; traverser.Traverse(module); #endregion return(contracts); }
/// <summary> /// Traverse the given assembly (located in options.Assembly) for contracts and return the contracts. /// </summary> /// <remarks> /// We use dictionary mapping special string ids that are unique to each member in an XML file to /// the contracts that that member has. /// </remarks> static IDictionary<string, XContract[]> GetContracts(Options options, DocTracker docTracker) { Contract.Requires(options != null); Contract.Requires(docTracker != null); Contract.Ensures(Contract.Result<IDictionary<string,XContract[]>>() != null); #region Establish host and load assembly Contract.Assume(options.resolvedPaths != null); var host = new CodeContractAwareHostEnvironment(options.libpaths); foreach (var p in options.resolvedPaths) { host.AddResolvedPath(p); } IModule module = host.LoadUnitFrom(options.assembly) as IModule; if (module == null || module == Dummy.Module || module == Dummy.Assembly) { Console.WriteLine("'{0}' is not a PE file containing a CLR module or assembly.", options.assembly); Environment.Exit(1); } #endregion #region Create the contracts dictionary Dictionary<string, XContract[]> contracts = new Dictionary<string, XContract[]>(StringComparer.Ordinal); //Use Ordinal compare for faster string comparison. #endregion #region Traverse module and extract contracts var contractsVisitor = new ContractVisitor(host, contracts, options, docTracker); var traverser = new ContractTraverser(host); traverser.PreorderVisitor = contractsVisitor; traverser.Traverse(module); #endregion return contracts; }
/// <summary> /// The main entry point for the program /// </summary> /// <param name="args">An assembly to be loaded by the program</param> public static void Main(string[] args) { var options = new Options(); options.Parse(args); if (options.HasErrors) { if (options.HelpRequested) { options.PrintOptions(""); } Environment.Exit(-1); } HostEnvironment host = new HostEnvironment(); IModule module = host.LoadUnitFrom(options.assembly) as IModule; if (module == null || module == Dummy.Module || module == Dummy.Assembly) { Console.WriteLine("'{0}' is not a PE file containing a CLR module or assembly.", options.assembly); return; } if (options.outToFile) { StreamWriter consoleStream = new StreamWriter("buildOutput.txt"); Console.SetOut(consoleStream); } string xmlDocSaveName; XDocument xDoc = null; //TODO: Use XmlReader instead of LINQ to XML XElement membersElement = null; if (!String.IsNullOrEmpty(options.xmlFile)) { //Load the XML File try { xDoc = XDocument.Load(options.xmlFile); } catch { Console.WriteLine(options.xmlFile + " is not a XML file."); return; } var docEl = xDoc.Element("doc"); //Navigate to "doc" if (docEl == null) { Console.WriteLine(options.xmlFile + " is not a valid XML reference file; it does not contain a \"doc\" element."); return; } membersElement = docEl.Element("members"); //Navigate to "members" if (membersElement == null) { Console.WriteLine(options.xmlFile + " is not a valid XML reference file; it does not contain a \"members\" element."); return; } xmlDocSaveName = options.xmlFile; } else { //Build a new XML File XDeclaration xDeclaration = new XDeclaration("1.0", null, null); membersElement = new XElement("members"); xDoc = new XDocument(xDeclaration, new XElement("doc", membersElement)); // membersElement = xDoc.Element("doc").Element("members"); string fileName = options.assembly; fileName = fileName.TrimEnd(".dll".ToCharArray()); xmlDocSaveName = fileName + ".xml"; } //Establish the traverser var contractMethods = new ContractMethods(host); IContractProvider contractProvider = new Microsoft.Cci.ILToCodeModel.LazyContractProvider(host, module, contractMethods); IMetadataVisitor traverser = new ContractTraverser(host, contractProvider, membersElement, options); traverser.Visit(module); xDoc.Save(xmlDocSaveName, SaveOptions.None); Console.Out.Close(); }