Пример #1
0
        public IEnumerable <string> GenerateAdditionalSourceCodeItems(
            Tuple <string, string[]> bondManifest,
            string[] manifestIds)
        {
            if (bondManifest.Item1 == null)
            {
                return(new string[0]);
            }

            if (manifestIds.Length == 1)
            {
                var map = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

                foreach (var className in bondManifest.Item2)
                {
                    var name = bondManifest.Item1 + "." + className;

                    var id = BondIdentifierHelpers.GenerateGuidFromName(name);

                    map[name] = id.ToString();
                }

                if (!string.Equals(
                        manifestIds[0],
                        map[bondManifest.Item1 + "." + bondManifest.Item2.Last()],
                        StringComparison.OrdinalIgnoreCase))
                {
                    return(new string[]
                    {
                        GenerateManifestOverrideCSharpClass(bondManifest.Item1, bondManifest.Item2.Last(), manifestIds[0]),
                    });
                }
            }

            return(new string[0]);
        }
Пример #2
0
        public void Initialize(string targetDir, params string[] files)
        {
            // Don't validate targetDir for empty. it will be created.
            if (targetDir == null)
            {
                throw new ArgumentNullException("targetDir");
            }

            if (files == null || files.Length <= 0)
            {
                throw new ArgumentNullException("files");
            }

            this.CacheDirectory = ResolveCacheDirectory(targetDir);

            if (!Directory.Exists(CacheDirectory))
            {
                Directory.CreateDirectory(CacheDirectory);
            }
            else
            {
                Utilities.EmptyDirectory(this.CacheDirectory);
            }

            // Get all manifests.
            var manifestsFromFiles = BinaryEtwObservable.BinaryManifestFromSequentialFiles(files)
                                     .ToEnumerable()
                                     .Where(a => !string.IsNullOrWhiteSpace(a.Manifest))
                                     .GroupBy(manifest => manifest.ManifestId, StringComparer.OrdinalIgnoreCase)
                                     .Select(grp => grp.First())
                                     .ToArray();

            if (manifestsFromFiles.Length == 0)
            {
                throw new Exception("No Bond manifests found. Ensure that the Bond manifests are written to the ETL file.");
            }

            int counter = 0;

            foreach (var manifestItem in manifestsFromFiles)
            {
                var codeSources = new List <string>();

                var namespaceAndClasses = this.ParseClassNames(manifestItem.Manifest);

                var assembliesOfThisManifest = new List <string>();

                if (!this.AreAnyTypesAlreadyInCache(namespaceAndClasses.Item2))
                {
                    string bondFileName = Path.Combine(CacheDirectory, "BondTypes" + counter + ".bond");

                    counter++;

                    File.WriteAllText(bondFileName, manifestItem.Manifest);
                    var codeGenerated = this.GenerateCSharpCode(bondFileName);

                    if (!string.IsNullOrWhiteSpace(codeGenerated))
                    {
                        codeSources.Add(codeGenerated);

                        foreach (var @class in namespaceAndClasses.Item2)
                        {
                            var completeName = namespaceAndClasses.Item1 + "." + @class;

                            var id = BondIdentifierHelpers.GenerateGuidFromName(@class.ToUpperInvariant());

                            // case when single manifest has multiple structs.
                            if (namespaceAndClasses.Item2.Length > 1 &&
                                !string.Equals(manifestItem.ManifestId, id.ToString(), StringComparison.OrdinalIgnoreCase))
                            {
                                codeSources.Add(GenerateAdditionalSourceCodeItems(namespaceAndClasses.Item1, @class, id));

                                this.Cache.Add(new TypeCacheItem
                                {
                                    Manifest = new EventManifest
                                    {
                                        ActivityId           = manifestItem.ActivityId,
                                        Manifest             = manifestItem.Manifest,
                                        ManifestId           = id.ToString(),
                                        OccurenceFileTimeUtc = manifestItem.OccurenceFileTimeUtc,
                                        Protocol             = manifestItem.Protocol,
                                        ReceiveFileTimeUtc   = manifestItem.ReceiveFileTimeUtc,
                                        Source = manifestItem.Source,
                                    },
                                });
                            }
                            else
                            {
                                codeSources.Add(GenerateAdditionalSourceCodeItems(namespaceAndClasses.Item1, @class, new Guid(manifestItem.ManifestId)));
                                this.Cache.Add(new TypeCacheItem
                                {
                                    Manifest = new EventManifest
                                    {
                                        ActivityId           = manifestItem.ActivityId,
                                        Manifest             = manifestItem.Manifest,
                                        ManifestId           = manifestItem.ManifestId,
                                        OccurenceFileTimeUtc = manifestItem.OccurenceFileTimeUtc,
                                        Protocol             = manifestItem.Protocol,
                                        ReceiveFileTimeUtc   = manifestItem.ReceiveFileTimeUtc,
                                        Source = manifestItem.Source,
                                    },
                                });
                            }
                        }

                        // After building the assembly, the types will be available.
                        string asm = Path.Combine(CacheDirectory, bondFileName + ".dll");
                        this.OutputAssembly(codeSources.ToArray(), asm);
                        assembliesOfThisManifest.Add(asm);

                        try
                        {
                            var types = assembliesOfThisManifest.Select(Assembly.LoadFile)
                                        .SelectMany(a => a.GetTypes().Where(type => type.IsPublic))
                                        .ToArray();

                            foreach (var item in types)
                            {
                                var targetCacheItem = this.FindMatchOrDefault(item.GUID.ToString());


                                if (targetCacheItem != null)
                                {
                                    targetCacheItem.Type = item;
                                }
                            }
                        }
                        catch
                        {
                            //Ignore this type
                            throw;
                        }
                    }
                }
            }
        }