public static int Main(string[] args) { ParseCommandLine(args); CommandLineTraceHandler.Enable(); if (s_listRules) { CompositionHost c = GetCompositionHost(); ExportCciSettings.StaticSettings = CciComparers.Default.GetEqualityComparer <ITypeReference>(); var rules = c.GetExports <IDifferenceRule>(); foreach (var rule in rules.Select(r => r.GetType().Name).OrderBy(r => r, StringComparer.OrdinalIgnoreCase)) { Console.WriteLine(rule); } return(0); } using (TextWriter output = GetOutput()) { if (DifferenceWriter.ExitCode != 0) { return(0); } if (output != Console.Out) { Trace.Listeners.Add(new TextWriterTraceListener(output) { Filter = new EventTypeFilter(SourceLevels.Error | SourceLevels.Warning) }); } try { BaselineDifferenceFilter filter = GetBaselineDifferenceFilter(); NameTable sharedNameTable = new NameTable(); HostEnvironment contractHost = new HostEnvironment(sharedNameTable); contractHost.UnableToResolve += new EventHandler <UnresolvedReference <IUnit, AssemblyIdentity> >(contractHost_UnableToResolve); contractHost.ResolveAgainstRunningFramework = s_resolveFx; contractHost.UnifyToLibPath = s_unifyToLibPaths; contractHost.AddLibPaths(HostEnvironment.SplitPaths(s_contractLibDirs)); IEnumerable <IAssembly> contractAssemblies = contractHost.LoadAssemblies(s_contractSet, s_contractCoreAssembly); if (s_ignoreDesignTimeFacades) { contractAssemblies = contractAssemblies.Where(a => !a.IsFacade()); } HostEnvironment implHost = new HostEnvironment(sharedNameTable); implHost.UnableToResolve += new EventHandler <UnresolvedReference <IUnit, AssemblyIdentity> >(implHost_UnableToResolve); implHost.ResolveAgainstRunningFramework = s_resolveFx; implHost.UnifyToLibPath = s_unifyToLibPaths; implHost.AddLibPaths(HostEnvironment.SplitPaths(s_implDirs)); if (s_warnOnMissingAssemblies) { implHost.LoadErrorTreatment = ErrorTreatment.TreatAsWarning; } // The list of contractAssemblies already has the core assembly as the first one (if _contractCoreAssembly was specified). IEnumerable <IAssembly> implAssemblies = implHost.LoadAssemblies(contractAssemblies.Select(a => a.AssemblyIdentity), s_warnOnIncorrectVersion); // Exit after loading if the code is set to non-zero if (DifferenceWriter.ExitCode != 0) { return(0); } ICciDifferenceWriter writer = GetDifferenceWriter(output, filter); writer.Write(s_implDirs, implAssemblies, s_contractSet, contractAssemblies); return(0); } catch (FileNotFoundException) { // FileNotFoundException will be thrown by GetBaselineDifferenceFilter if it doesn't find the baseline file // OR if GetComparers doesn't find the remap file. return(2); } } }
public static void Main(string[] args) { string seeds = null; string contracts = null; string facadePath = null; Version assemblyFileVersion = null; bool clearBuildAndRevision = false; bool ignoreMissingTypes = false; bool ignoreBuildAndRevisionMismatch = false; bool buildDesignTimeFacades = false; string inclusionContracts = null; ErrorTreatment seedLoadErrorTreatment = ErrorTreatment.Default; ErrorTreatment contractLoadErrorTreatment = ErrorTreatment.Default; string[] seedTypePreferencesUnsplit = null; bool forceZeroVersionSeeds = false; bool producePdb = true; string partialFacadeAssemblyPath = null; bool parsingSucceeded = CommandLineParser.ParseForConsoleApplication((parser) => { parser.DefineQualifier("facadePath", ref facadePath, "Path to output the facades."); parser.DefineQualifier("seeds", ref seeds, "Path to the seed assemblies. Can contain multiple assemblies or directories delimited by ',' or ';'."); parser.DefineQualifier("contracts", ref contracts, "Path to the contract assemblies. Can contain multiple assemblies or directories delimited by ',' or ';'."); parser.DefineOptionalQualifier("assemblyFileVersion", ref assemblyFileVersion, "Override the AssemblyFileVersion attribute from the contract with the given version for the generated facade."); parser.DefineOptionalQualifier("clearBuildAndRevision", ref clearBuildAndRevision, "Generate facade assembly version x.y.0.0 for contract version x.y.z.w"); parser.DefineOptionalQualifier("ignoreBuildAndRevisionMismatch", ref ignoreBuildAndRevisionMismatch, "Ignore a mismatch in revision and build for partial facade."); parser.DefineOptionalQualifier("ignoreMissingTypes", ref ignoreMissingTypes, "Ignore types that cannot be found in the seed assemblies. This is not recommended but is sometimes helpful while hacking around or trying to produce partial facades."); parser.DefineOptionalQualifier("designTime", ref buildDesignTimeFacades, "Enable design-time facade generation (marks facades with reference assembly flag and attribute)."); parser.DefineOptionalQualifier("include", ref inclusionContracts, "Add types from these contracts to the facades. Can contain multiple assemblies or directories delimited by ',' or ';'."); parser.DefineOptionalQualifier("seedError", ref seedLoadErrorTreatment, "Error handling for seed assembly load failure."); parser.DefineOptionalQualifier("contractError", ref seedLoadErrorTreatment, "Error handling for contract assembly load failure."); parser.DefineOptionalQualifier("preferSeedType", ref seedTypePreferencesUnsplit, "Set which seed assembly to choose for a given type when it is defined in more than one assembly. Format: FullTypeName=PreferredSeedAssemblyName"); parser.DefineOptionalQualifier("forceZeroVersionSeeds", ref forceZeroVersionSeeds, "Forces all seed assembly versions to 0.0.0.0, regardless of their true version."); parser.DefineOptionalQualifier("partialFacadeAssemblyPath", ref partialFacadeAssemblyPath, "Specifies the path to a single partial facade assembly, into which appropriate type forwards will be added to satisfy the given contract. If this option is specified, only a single partial assembly and a single contract may be given."); parser.DefineOptionalQualifier("producePdb", ref producePdb, "Specifices if a PDB file should be produced for the resulting partial facade."); }, args); if (!parsingSucceeded) { return; } CommandLineTraceHandler.Enable(); if (!Directory.Exists(facadePath)) { Directory.CreateDirectory(facadePath); } var nameTable = new NameTable(); var internFactory = new InternFactory(); try { Dictionary <string, string> seedTypePreferences = ParseSeedTypePreferences(seedTypePreferencesUnsplit); using (var contractHost = new HostEnvironment(nameTable, internFactory)) using (var seedHost = new HostEnvironment(nameTable, internFactory)) { contractHost.LoadErrorTreatment = contractLoadErrorTreatment; seedHost.LoadErrorTreatment = seedLoadErrorTreatment; var contractAssemblies = LoadAssemblies(contractHost, contracts); IReadOnlyDictionary <string, IEnumerable <string> > docIdTable = GenerateDocIdTable(contractAssemblies, inclusionContracts); IAssembly[] seedAssemblies = LoadAssemblies(seedHost, seeds).ToArray(); IAssemblyReference seedCoreAssemblyRef = ((Microsoft.Cci.Immutable.PlatformType)seedHost.PlatformType).CoreAssemblyRef; if (forceZeroVersionSeeds) { // Create a deep copier, copy the seed assemblies, and zero out their versions. var copier = new MetadataDeepCopier(seedHost); for (int i = 0; i < seedAssemblies.Length; i++) { var mutableSeed = copier.Copy(seedAssemblies[i]); mutableSeed.Version = new Version(0, 0, 0, 0); // Copy the modified seed assembly back. seedAssemblies[i] = mutableSeed; if (mutableSeed.Name.UniqueKey == seedCoreAssemblyRef.Name.UniqueKey) { seedCoreAssemblyRef = mutableSeed; } } } var typeTable = GenerateTypeTable(seedAssemblies); var facadeGenerator = new FacadeGenerator(seedHost, contractHost, docIdTable, typeTable, seedTypePreferences, clearBuildAndRevision, buildDesignTimeFacades, assemblyFileVersion); if (partialFacadeAssemblyPath != null) { if (contractAssemblies.Count() != 1) { throw new FacadeGenerationException( "When partialFacadeAssemblyPath is specified, only exactly one corresponding contract assembly can be specified."); } IAssembly contractAssembly = contractAssemblies.First(); IAssembly partialFacadeAssembly = seedHost.LoadAssembly(partialFacadeAssemblyPath); if (contractAssembly.Name != partialFacadeAssembly.Name || contractAssembly.Version.Major != partialFacadeAssembly.Version.Major || contractAssembly.Version.Minor != partialFacadeAssembly.Version.Minor || (!ignoreBuildAndRevisionMismatch && contractAssembly.Version.Build != partialFacadeAssembly.Version.Build) || (!ignoreBuildAndRevisionMismatch && contractAssembly.Version.Revision != partialFacadeAssembly.Version.Revision) || contractAssembly.GetPublicKeyToken() != partialFacadeAssembly.GetPublicKeyToken()) { throw new FacadeGenerationException( string.Format("The partial facade assembly's name, version, and public key token must exactly match the contract to be filled. Contract: {0}, Facade: {1}", contractAssembly.AssemblyIdentity, partialFacadeAssembly.AssemblyIdentity)); } Assembly filledPartialFacade = facadeGenerator.GenerateFacade(contractAssembly, seedCoreAssemblyRef, ignoreMissingTypes, overrideContractAssembly: partialFacadeAssembly); string pdbLocation = null; if (producePdb) { string pdbFolder = Path.GetDirectoryName(partialFacadeAssemblyPath); pdbLocation = Path.Combine(pdbFolder, contractAssembly.Name + ".pdb"); if (producePdb && !File.Exists(pdbLocation)) { pdbLocation = null; Trace.TraceWarning("No PDB file present for un-transformed partial facade. No PDB will be generated."); } } OutputFacadeToFile(facadePath, seedHost, filledPartialFacade, contractAssembly, pdbLocation); } else { foreach (var contract in contractAssemblies) { Assembly facade = facadeGenerator.GenerateFacade(contract, seedCoreAssemblyRef, ignoreMissingTypes); if (facade == null) { #if !COREFX Debug.Assert(Environment.ExitCode != 0); #endif continue; } OutputFacadeToFile(facadePath, seedHost, facade, contract); } } } } catch (FacadeGenerationException ex) { Trace.TraceError(ex.Message); #if !COREFX Debug.Assert(Environment.ExitCode != 0); #endif } }
public static void Main(string[] args) { string seeds = null; string contracts = null; string facadePath = null; Version assemblyFileVersion = null; bool clearBuildAndRevision = false; bool ignoreMissingTypes = false; bool ignoreBuildAndRevisionMismatch = false; bool buildDesignTimeFacades = false; string inclusionContracts = null; ErrorTreatment seedLoadErrorTreatment = ErrorTreatment.Default; ErrorTreatment contractLoadErrorTreatment = ErrorTreatment.Default; string[] seedTypePreferencesUnsplit = null; bool forceZeroVersionSeeds = false; bool producePdb = true; string partialFacadeAssemblyPath = null; bool parsingSucceeded = CommandLineParser.ParseForConsoleApplication((parser) => { parser.DefineQualifier("facadePath", ref facadePath, "Path to output the facades."); parser.DefineQualifier("seeds", ref seeds, "Path to the seed assemblies. Can contain multiple assemblies or directories delimited by ',' or ';'."); parser.DefineQualifier("contracts", ref contracts, "Path to the contract assemblies. Can contain multiple assemblies or directories delimited by ',' or ';'."); parser.DefineOptionalQualifier("assemblyFileVersion", ref assemblyFileVersion, "Override the AssemblyFileVersion attribute from the contract with the given version for the generated facade."); parser.DefineOptionalQualifier("clearBuildAndRevision", ref clearBuildAndRevision, "Generate facade assembly version x.y.0.0 for contract version x.y.z.w"); parser.DefineOptionalQualifier("ignoreBuildAndRevisionMismatch", ref ignoreBuildAndRevisionMismatch, "Ignore a mismatch in revision and build for partial facade."); parser.DefineOptionalQualifier("ignoreMissingTypes", ref ignoreMissingTypes, "Ignore types that cannot be found in the seed assemblies. This is not recommended but is sometimes helpful while hacking around or trying to produce partial facades."); parser.DefineOptionalQualifier("designTime", ref buildDesignTimeFacades, "Enable design-time facade generation (marks facades with reference assembly flag and attribute)."); parser.DefineOptionalQualifier("include", ref inclusionContracts, "Add types from these contracts to the facades. Can contain multiple assemblies or directories delimited by ',' or ';'."); parser.DefineOptionalQualifier("seedError", ref seedLoadErrorTreatment, "Error handling for seed assembly load failure."); parser.DefineOptionalQualifier("contractError", ref seedLoadErrorTreatment, "Error handling for contract assembly load failure."); parser.DefineOptionalQualifier("preferSeedType", ref seedTypePreferencesUnsplit, "Set which seed assembly to choose for a given type when it is defined in more than one assembly. Format: FullTypeName=PreferredSeedAssemblyName"); parser.DefineOptionalQualifier("forceZeroVersionSeeds", ref forceZeroVersionSeeds, "Forces all seed assembly versions to 0.0.0.0, regardless of their true version."); parser.DefineOptionalQualifier("partialFacadeAssemblyPath", ref partialFacadeAssemblyPath, "Specifies the path to a single partial facade assembly, into which appropriate type forwards will be added to satisfy the given contract. If this option is specified, only a single partial assembly and a single contract may be given."); parser.DefineOptionalQualifier("producePdb", ref producePdb, "Specifices if a PDB file should be produced for the resulting partial facade."); }, args); if (!parsingSucceeded) { return; } CommandLineTraceHandler.Enable(); Generator.Execute( seeds, contracts, facadePath, assemblyFileVersion, clearBuildAndRevision, ignoreMissingTypes, ignoreBuildAndRevisionMismatch, buildDesignTimeFacades, inclusionContracts, seedLoadErrorTreatment, contractLoadErrorTreatment, seedTypePreferencesUnsplit, forceZeroVersionSeeds, producePdb, partialFacadeAssemblyPath); }