public XDocument Generate() { TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Enrichers:"); for (int i = 0; i < this.Enrichers.Count; i++) { IEnricher enricher = this.Enrichers[i]; TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "[{0}] {1}", i, enricher.GetType().FullName); } TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Filters:"); for (int i = 0; i < this.AssetFilters.Count; i++) { TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "[{0}] {1}", i, this.AssetFilters[i].GetType().FullName); } XDocument ret = new XDocument(); IAssemblyLoader assemblyLoader = new ReflectionOnlyAssemblyLoader( this._cache, this._assemblyPaths.Select(Path.GetDirectoryName)); this._assemblies = this._assemblyPaths.Select(assemblyLoader.LoadFrom).ToArray(); XNamespace defaultNs = string.Empty; // pass in assemblyLoader instead IAssetResolver assetResolver = new AssetResolver(assemblyLoader); // collect phase zero assets List<AssetIdentifier> assets = this.DiscoverAssets(assetResolver, this._assemblies).ToList(); // initiate output document creation ret.Add(new XElement(defaultNs + "bundle")); IProcessingContext pctx = new ProcessingContext(this._cache, this._filters, assemblyLoader, assetResolver, ret.Root, null, -1); foreach (IEnricher enricher in this._enrichers) enricher.RegisterNamespace(pctx); // asset related classes HashSet<AssetIdentifier> emittedAssets = new HashSet<AssetIdentifier>(); TraceSources.GeneratorSource.TraceEvent(TraceEventType.Start, 0, "Generating document"); int phase = 0; HashSet<AssetIdentifier> referencedAssets = new HashSet<AssetIdentifier>(); long lastProgressOutput = Stopwatch.GetTimestamp(); // main output loop while (assets.Count > 0) { int phaseAssetCount = 0; using (TraceSources.GeneratorSource.TraceActivity("Phase {0} ({1:N0} assets)", phase, assets.Count)) { foreach (AssetIdentifier asset in assets) { // skip already emitted assets if (!emittedAssets.Add(asset)) continue; phaseAssetCount++; if (((Stopwatch.GetTimestamp() - lastProgressOutput)/(double) Stopwatch.Frequency) > 5.0) { TraceSources.GeneratorSource.TraceEvent(TraceEventType.Information, 0, "Phase {0} progress {1:P1} ({2:N0}/{3:N0})", phase, phaseAssetCount/(double) assets.Count, phaseAssetCount, assets.Count); lastProgressOutput = Stopwatch.GetTimestamp(); } TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Generating {0}", asset); // get hierarchy LinkedList<AssetIdentifier> hierarchy = new LinkedList<AssetIdentifier>(); foreach (AssetIdentifier assetIdentifier in assetResolver.GetAssetHierarchy(asset)) hierarchy.AddFirst(assetIdentifier); if (hierarchy.First != null) { this.BuildHierarchy(assetResolver, ret.Root, hierarchy.First, asset, referencedAssets, emittedAssets, phase); } } ++phase; assets.Clear(); referencedAssets.ExceptWith(emittedAssets); assets = referencedAssets.ToList(); referencedAssets.Clear(); } } TraceSources.GeneratorSource.TraceEvent(TraceEventType.Stop, 0, "Generating document"); return ret; }
public XDocument Generate() { TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Enrichers:"); for (int i = 0; i < this.Enrichers.Count; i++) { IEnricher enricher = this.Enrichers[i]; TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "[{0}] {1}", i, enricher.GetType().FullName); } TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Filters:"); for (int i = 0; i < this.AssetFilters.Count; i++) { TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "[{0}] {1}", i, this.AssetFilters[i].GetType().FullName); } XDocument ret = new XDocument(); this._assemblies = this._assemblyPaths.Select(this.LoadReflectionOnly).ToArray(); XNamespace defaultNs = string.Empty; IAssetResolver assetResolver = new AssetResolver(this.EnumerateAssemblies().ToArray()); // collect phase zero assets List<AssetIdentifier> assets = this.DiscoverAssets(assetResolver, this._assemblies).ToList(); // initiate output document creation ret.Add(new XElement(defaultNs + "bundle")); IProcessingContext pctx = new ProcessingContext(this._filters, assetResolver, ret.Root, null, -1); foreach (IEnricher enricher in this._enrichers) enricher.RegisterNamespace(pctx); // asset related classes HashSet<AssetIdentifier> emittedAssets = new HashSet<AssetIdentifier>(); TraceSources.GeneratorSource.TraceEvent(TraceEventType.Start, 0, "Generating document"); int phase = 0; HashSet<AssetIdentifier> referencedAssets = new HashSet<AssetIdentifier>(); // main output loop while (assets.Count > 0) { TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Processing phase {0}", phase); foreach (AssetIdentifier asset in assets) { // skip already emitted assets if (!emittedAssets.Add(asset)) continue; // hack: if (asset.AssetId.Substring(asset.TypeMarker.Length + 1).StartsWith("<PrivateImplementationDetails>{", StringComparison.Ordinal)) continue; TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Generating {0}", asset); // get hierarchy LinkedList<AssetIdentifier> hierarchy = new LinkedList<AssetIdentifier>(); foreach (AssetIdentifier assetIdentifier in assetResolver.GetAssetHierarchy(asset)) hierarchy.AddFirst(assetIdentifier); this.BuildHierarchy(assetResolver, ret.Root, hierarchy.First, asset, referencedAssets, emittedAssets, phase); } ++phase; assets.Clear(); referencedAssets.ExceptWith(emittedAssets); assets = referencedAssets.ToList(); referencedAssets.Clear(); } TraceSources.GeneratorSource.TraceEvent(TraceEventType.Stop, 0, "Generating document"); return ret; }