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)); }
private static string RelativeName(TypeDefinition type, TypeDefinition current, Options options, string errorContext) { if (type.IsGenericParameter) { return(type.Name); } if (type.DeclaringType != null) { return(RelativeName(type.DeclaringType, current, options, errorContext) + "_" + BaseTypeScriptName(type)); } if (type.Module.Assembly.Equals(current.Module.Assembly) && type.Namespace == current.Namespace) { string relativeNamespace = RelativeNamespace(type, current); return(CombineNamespace(relativeNamespace, BaseTypeScriptName(type))); } else if (type.IsEnum && options.IsExternal(type)) { return("External." + BaseTypeScriptName(type)); } else { var nsReference = GetNamespaceReference(options, type); if (nsReference == null) { if (type.Interfaces.Any(i => i.InterfaceType.FullName == typeof(IEnumerable).FullName)) { return("Array"); } throw new InvalidOperationException($"{errorContext}: Type {type.ToString()} is declared in the assembly '{type.Module.Assembly.Name}', but no React directory for it is found."); } return(CombineNamespace(nsReference.VariableName, BaseTypeScriptName(type))); } }
private static string TypeScriptNameInternal(TypeReference type, TypeDefinition current, Options options, string errorContext) { type = type.UnNullify(); if (type.FullName == typeof(Boolean).FullName) { return("boolean"); } if (type.FullName == typeof(Char).FullName) { return("string"); } if (type.FullName == typeof(SByte).FullName || type.FullName == typeof(Byte).FullName || type.FullName == typeof(Int16).FullName || type.FullName == typeof(UInt16).FullName || type.FullName == typeof(Int32).FullName || type.FullName == typeof(UInt32).FullName || type.FullName == typeof(Int64).FullName || type.FullName == typeof(UInt64).FullName || type.FullName == typeof(Decimal).FullName || type.FullName == typeof(Single).FullName || type.FullName == typeof(Double).FullName) { return("number"); } if (type.FullName == typeof(String).FullName) { return("string"); } if (type.FullName == typeof(DateTime).FullName) { return("string"); } if (type.FullName == typeof(Guid).FullName || type.FullName == typeof(Byte[]).FullName || type.FullName == typeof(TimeSpan).FullName) { return("string"); } if (type.IsGenericParameter) { return(type.Name); } if (type is GenericInstanceType git) { return(RelativeName(type.Resolve(), current, options, errorContext) + "<" + string.Join(", ", git.GenericArguments.Select(a => TypeScriptName(a, current, options, errorContext)).ToList()) + ">"); } else if (type.HasGenericParameters) { return(RelativeName(type.Resolve(), current, options, errorContext) + "<" + string.Join(", ", type.GenericParameters.Select(gp => gp.Name)) + ">"); } else if (type is ArrayType at) { return(TypeScriptName(at.ElementType, current, options, errorContext) + "[]"); } else { return(RelativeName(type.Resolve(), current, options, errorContext)); } }