예제 #1
0
        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, "Filter:");
            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._container,
                                                            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;
        }
예제 #2
0
        private void BuildHierarchy(IAssetResolver assetResolver,
                                    XElement parentNode,
                                    LinkedListNode<AssetIdentifier> hierarchy,
                                    AssetIdentifier asset,
                                    HashSet<AssetIdentifier> references,
                                    HashSet<AssetIdentifier> emittedAssets,
                                    int phase)
        {
            if (hierarchy == null)
                return;

            IAssemblyLoader assemblyLoader =
                new ReflectionOnlyAssemblyLoader(this._cache,
                                                 this._assemblyPaths.Select(Path.GetDirectoryName));


            AssetIdentifier aid = hierarchy.Value;
            IProcessingContext pctx = new ProcessingContext(this._cache,
                                                            this._container,
                                                            this._filters,
                                                            assemblyLoader,
                                                            assetResolver,
                                                            parentNode,
                                                            references,
                                                            phase);

            XElement newElement;

            // add asset to list of generated assets
            emittedAssets.Add(aid);

            // dispatch depending on type
            switch (aid.Type)
            {
                case AssetType.Namespace:
                    newElement = parentNode.XPathSelectElement(string.Format("namespace[@assetId = '{0}']", aid));
                    if (newElement == null)
                        newElement = this.GenerateNamespaceElement(pctx, aid);
                    break;
                case AssetType.Type:
                    newElement = parentNode.XPathSelectElement(string.Format("*[@assetId = '{0}']", aid));
                    if (newElement == null)
                        newElement = this.GenerateTypeElement(pctx, aid);
                    break;
                case AssetType.Method:
                    newElement = parentNode.XPathSelectElement(string.Format("*[@assetId = '{0}']", aid));
                    if (newElement == null)
                        newElement = this.GenerateMethodElement(pctx, aid);
                    break;
                case AssetType.Field:
                    newElement = parentNode.XPathSelectElement(string.Format("field[@assetId = '{0}']", aid));
                    if (newElement == null)
                        newElement = this.GenerateFieldElement(pctx, aid);
                    break;
                case AssetType.Event:
                    newElement = parentNode.XPathSelectElement(string.Format("event[@assetId = '{0}']", aid));
                    if (newElement == null)
                        newElement = this.GenerateEventElement(pctx, aid);
                    break;
                case AssetType.Property:
                    newElement = parentNode.XPathSelectElement(string.Format("property[@assetId = '{0}']", aid));
                    if (newElement == null)
                        newElement = this.GeneratePropertyElement(pctx, aid);
                    break;
                case AssetType.Assembly:
                    newElement = parentNode.XPathSelectElement(string.Format("assembly[@assetId = '{0}']", aid));
                    if (newElement == null)
                        newElement = this.GenerateAssemblyElement(pctx, aid);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            this.BuildHierarchy(assetResolver, newElement, hierarchy.Next, asset, references, emittedAssets, phase);
        }