Пример #1
0
        public string Process(string templateFile, string[] referenceList, string projectFile)
        {
            var options = new Options
            {
                TemplateFileName   = templateFile,
                CurrentNamespace   = Path.GetFileNameWithoutExtension(templateFile),
                CurrentAssembly    = Path.GetFileNameWithoutExtension(projectFile).Replace(".React", ".Entities"),
                AssemblyReferences = (from r in referenceList
                                      where r.Contains(".Entities")
                                      let reactDirectory = ReactDirectoryCache.GetOrAdd(r, FindReactDirectory)
                                                           select new AssemblyReference
                {
                    AssemblyName = Path.GetFileNameWithoutExtension(r),
                    AssemblyFullPath = r,
                    ReactDirectory = reactDirectory,
                    AllTypescriptFiles = AllFilesCache.GetOrAdd(reactDirectory, GetAllTypescriptFiles),
                }).ToDictionary(a => a.AssemblyName),
                AllReferences = referenceList.ToDictionary(a => Path.GetFileNameWithoutExtension(a)),
            };

            PreloadingAssemblyResolver resolver = new PreloadingAssemblyResolver(referenceList);

            return(EntityDeclarationGenerator.Process(options, resolver));
        }
Пример #2
0
        public static int Main(string[] args)
        {
            Stopwatch sw = Stopwatch.StartNew();

            string intermediateAssembly = args[0];

            string[] references = File.ReadAllLines(args[1]);
            string[] content    = File.ReadAllLines(args[2]);

            var log = Console.Out;

            log.WriteLine("Starting SignumTSGenerator");

            bool hasPdb = File.Exists(Path.ChangeExtension(intermediateAssembly, ".pdb"));

            AssemblyDefinition reactAssembly = AssemblyDefinition.ReadAssembly(intermediateAssembly, new ReaderParameters
            {
                ReadingMode          = ReadingMode.Deferred,
                ReadSymbols          = hasPdb,
                InMemory             = true,
                SymbolReaderProvider = hasPdb ? new PdbReaderProvider() : null
            });


            if (AlreadyProcessed(reactAssembly))
            {
                log.WriteLine("SignumTSGenerator already processed: {0}", intermediateAssembly);
                return(0);
            }

            PreloadingAssemblyResolver resolver = new PreloadingAssemblyResolver(references);

            var assemblyReferences = (from r in references
                                      where r.Contains(".Entities")
                                      let reactDirectory = FindReactDirectory(r)
                                                           select new AssemblyReference
            {
                AssemblyName = Path.GetFileNameWithoutExtension(r),
                AssemblyFullPath = r,
                ReactDirectory = reactDirectory,
                AllTypescriptFiles = GetAllTypescriptFiles(reactDirectory),
            }).ToDictionary(a => a.AssemblyName);

            var entitiesAssembly          = Path.GetFileNameWithoutExtension(intermediateAssembly).Replace(".React", ".Entities");
            var entitiesAssemblyReference = assemblyReferences.GetOrThrow(entitiesAssembly);
            var entitiesModule            = ModuleDefinition.ReadModule(entitiesAssemblyReference.AssemblyFullPath, new ReaderParameters {
                AssemblyResolver = resolver
            });
            var options = new AssemblyOptions
            {
                CurrentAssembly    = entitiesAssembly,
                AssemblyReferences = assemblyReferences,
                AllReferences      = references.ToDictionary(a => Path.GetFileNameWithoutExtension(a)),
                ModuleDefinition   = entitiesModule,
                Resolver           = resolver,
            };


            var currentDir = Directory.GetCurrentDirectory();
            var files      = content
                             .Where(file => Path.GetExtension(file) == ".t4s")
                             .Select(file => Path.Combine(currentDir, file))
                             .ToList();

            bool hasErrors = false;

            foreach (var file in files)
            {
                try
                {
                    string result = EntityDeclarationGenerator.Process(options, file, Path.GetFileNameWithoutExtension(file));

                    var targetFile = Path.ChangeExtension(file, ".ts");
                    if (File.Exists(targetFile) && File.ReadAllText(targetFile) == result)
                    {
                        log.WriteLine($"Skipping {targetFile} (Up to date)");
                    }
                    else
                    {
                        log.WriteLine($"Writing {targetFile}");
                        File.WriteAllText(targetFile, result);
                    }
                }
                catch (Exception ex)
                {
                    hasErrors = true;
                    log.WriteLine($"Error in {file}");
                    log.WriteLine(ex.Message);
                }
            }

            MarkAsProcessed(reactAssembly, resolver);

            reactAssembly.Write(intermediateAssembly, new WriterParameters
            {
                WriteSymbols         = hasPdb,
                SymbolWriterProvider = hasPdb ? new PdbWriterProvider() : null
            });

            log.WriteLine($"SignumTSGenerator finished in {sw.ElapsedMilliseconds.ToString()}ms");

            Console.WriteLine();

            return(hasErrors ? -1 : 0);
        }
        internal static string Process(Options options, PreloadingAssemblyResolver resolver)
        {
            StringBuilder sb = new StringBuilder();

            var module = ModuleDefinition.ReadModule(options.CurrentAssemblyReference.AssemblyFullPath, new ReaderParameters {
                AssemblyResolver = resolver
            });

            var entities = resolver.SignumEntities;

            Cache = new TypeCache(entities);

            GetNamespaceReference(options, Cache.ModifiableEntity);

            var exportedTypes = module.Types.Where(a => a.Namespace == options.CurrentNamespace).ToList();

            if (exportedTypes.Count == 0)
            {
                throw new InvalidOperationException($"Assembly '{options.CurrentAssembly}' has not types in namespace '{options.CurrentNamespace}'");
            }

            var imported = module.Assembly.CustomAttributes.Where(at => at.AttributeType.FullName == Cache.ImportInTypeScriptAttribute.FullName)
                           .Where(at => (string)at.ConstructorArguments[1].Value == options.CurrentNamespace)
                           .Select(at => ((TypeReference)at.ConstructorArguments[0].Value).Resolve())
                           .ToList();

            var importedMessage = imported.Where(a => a.Name.EndsWith("Message")).ToList();
            var importedEnums   = imported.Except(importedMessage).ToList();

            var entityResults = (from type in exportedTypes
                                 where !type.IsValueType && (type.InTypeScript() ?? IsModifiableEntity(type))
                                 select new
            {
                ns = type.Namespace,
                type,
                text = EntityInTypeScript(type, options),
            }).ToList();

            var interfacesResults = (from type in exportedTypes
                                     where type.IsInterface && (type.InTypeScript() ?? AllInterfaces(type).Any(i => i.FullName == Cache.IEntity.FullName))
                                     select new
            {
                ns = type.Namespace,
                type,
                text = EntityInTypeScript(type, options),
            }).ToList();

            var usedEnums = (from type in entityResults.Select(a => a.type)
                             from p in GetAllProperties(type)
                             let pt = (p.PropertyType.ElementType() ?? p.PropertyType).UnNullify()
                                      let def = pt.Resolve()
                                                where def != null && def.IsEnum
                                                select def).Distinct().ToList();

            var symbolResults = (from type in exportedTypes
                                 where !type.IsValueType && type.IsStaticClass() && type.ContainsAttribute("AutoInitAttribute") &&
                                 (type.InTypeScript() ?? true)
                                 select new
            {
                ns = type.Namespace,
                type,
                text = SymbolInTypeScript(type, options),
            }).ToList();

            var enumResult = (from type in exportedTypes
                              where type.IsEnum && (type.InTypeScript() ?? usedEnums.Contains(type))
                              select new
            {
                ns = type.Namespace,
                type,
                text = EnumInTypeScript(type, options),
            }).ToList();

            var externalEnums = (from type in usedEnums.Where(options.IsExternal).Concat(importedEnums)
                                 select new
            {
                ns = options.CurrentNamespace + ".External",
                type,
                text = EnumInTypeScript(type, options),
            }).ToList();

            var externalMessages = (from type in importedMessage
                                    select new
            {
                ns = options.CurrentNamespace + ".External",
                type,
                text = MessageInTypeScript(type, options),
            }).ToList();

            var messageResults = (from type in exportedTypes
                                  where type.IsEnum && type.Name.EndsWith("Message")
                                  select new
            {
                ns = type.Namespace,
                type,
                text = MessageInTypeScript(type, options),
            }).ToList();

            var queryResult = (from type in exportedTypes
                               where type.IsEnum && type.Name.EndsWith("Query")
                               select new
            {
                ns = type.Namespace,
                type,
                text = QueryInTypeScript(type, options),
            }).ToList();

            var namespaces = entityResults
                             .Concat(interfacesResults)
                             .Concat(enumResult)
                             .Concat(messageResults)
                             .Concat(queryResult)
                             .Concat(symbolResults)
                             .Concat(externalEnums)
                             .Concat(externalMessages)
                             .GroupBy(a => a.ns)
                             .OrderBy(a => a.Key);


            foreach (var ns in namespaces)
            {
                var key = RemoveNamespace(ns.Key.ToString(), options.CurrentNamespace);

                if (key.Length == 0)
                {
                    foreach (var item in ns.OrderBy(a => a.type.Name))
                    {
                        sb.AppendLine(item.text);
                    }
                }
                else
                {
                    sb.AppendLine("export namespace " + key + " {");
                    sb.AppendLine();

                    foreach (var item in ns.OrderBy(a => a.type.Name))
                    {
                        foreach (var line in item.text.Split(new[] { "\r\n" }, StringSplitOptions.None))
                        {
                            sb.AppendLine("  " + line);
                        }
                    }

                    sb.AppendLine("}");
                    sb.AppendLine();
                }
            }

            var code = sb.ToString();

            return(WriteFillFile(options, code));
        }
Пример #4
0
        public static int Main(string[] args)
        {
            var log = Console.Out;

            Stopwatch sw = Stopwatch.StartNew();

            string intermediateAssembly = args[0];

            string[] references = File.ReadAllLines(args[1]);
            string[] content    = File.ReadAllLines(args[2]);

            log.WriteLine("Starting SignumTSGenerator");

            var assemblyReferences = (from r in references
                                      where r.Contains(".Entities")
                                      let reactDirectory = FindReactDirectory(r)
                                                           select new AssemblyReference
            {
                AssemblyName = Path.GetFileNameWithoutExtension(r),
                AssemblyFullPath = r,
                ReactDirectory = reactDirectory,
                AllTypescriptFiles = GetAllTypescriptFiles(reactDirectory),
            }).ToDictionary(a => a.AssemblyName);

            var entitiesAssembly          = Path.GetFileNameWithoutExtension(intermediateAssembly).Replace(".React", ".Entities");
            var entitiesAssemblyReference = assemblyReferences.GetOrThrow(entitiesAssembly);

            var currentDir = Directory.GetCurrentDirectory();
            var files      = content
                             .Where(file => Path.GetExtension(file) == ".t4s")
                             .Select(file => Path.Combine(currentDir, file))
                             .ToList();

            var upToDateContent = string.Join("\r\n",
                                              new[] { entitiesAssemblyReference.AssemblyFullPath }
                                              .Concat(files)
                                              .OrderBy(a => a)
                                              .Select(f => File.GetLastWriteTimeUtc(f).ToString("o") + " " + Path.GetFileName(f)));

            var signumUpToDatePath = Path.Combine(Path.GetDirectoryName(args[1]), "SignumUpToDate.txt");

            if (File.Exists(signumUpToDatePath) && File.ReadAllText(signumUpToDatePath) == upToDateContent)
            {
                log.WriteLine($"SignumTSGenerator already processed ({sw.ElapsedMilliseconds.ToString()}ms)");
                return(0);
            }

            var entityResolver = new PreloadingAssemblyResolver(references);
            var entitiesModule = ModuleDefinition.ReadModule(entitiesAssemblyReference.AssemblyFullPath, new ReaderParameters
            {
                AssemblyResolver = entityResolver
            });

            var options = new AssemblyOptions
            {
                CurrentAssembly    = entitiesAssembly,
                AssemblyReferences = assemblyReferences,
                AllReferences      = references.ToDictionary(a => Path.GetFileNameWithoutExtension(a)),
                ModuleDefinition   = entitiesModule,
                Resolver           = entityResolver,
            };

            bool hasErrors = false;

            foreach (var file in files)
            {
                try
                {
                    string result = EntityDeclarationGenerator.Process(options, file, Path.GetFileNameWithoutExtension(file));

                    var targetFile = Path.ChangeExtension(file, ".ts");
                    if (File.Exists(targetFile) && File.ReadAllText(targetFile) == result)
                    {
                        log.WriteLine($"Skipping {targetFile} (Up to date)");
                    }
                    else
                    {
                        log.WriteLine($"Writing {targetFile}");
                        File.WriteAllText(targetFile, result);
                    }
                }
                catch (Exception ex)
                {
                    hasErrors = true;
                    log.WriteLine($"{file}:error STSG0001:{ex.Message}");
                    log.WriteLine(ex.Message);
                }
            }

            if (hasErrors)
            {
                log.WriteLine($"SignumTSGenerator finished with errors ({sw.ElapsedMilliseconds.ToString()}ms)");
                Console.WriteLine();
                return(0);
            }
            else
            {
                File.WriteAllText(signumUpToDatePath, upToDateContent);
                log.WriteLine($"SignumTSGenerator finished ({sw.ElapsedMilliseconds.ToString()}ms)");
                Console.WriteLine();
                return(0);
            }
        }