internal TypeCodeGenerator(Type type, NamespaceCodeGenerator namespaceCodeGenerator)
 {
     this.type = type;
     this.namespaceCodeGenerator = namespaceCodeGenerator;
     TypescriptType = TypescriptTypeStore.AddType(type, false);
 }
Example #2
0
        public static TypescriptType AddType(Type type, bool fromProperty)
        {
            TypescriptType typescriptType;

            if (store.TryGetValue(type, out typescriptType) == false)
            {
                string currentNamespace = type.Namespace;

                typescriptType = new TypescriptType(type, IsExcluded(type));

                typescriptType.NamespaceName = type.Namespace;

                store.Add(type, typescriptType);

                string nonGenericName = GetNonGenericName(type);
                string nonGenericNameWithNamespace = nonGenericName;
                if (string.IsNullOrWhiteSpace(type.Namespace) == false)
                {
                    nonGenericNameWithNamespace = $"{type.Namespace}.{nonGenericName}";
                }
                string baseAffectedName;
                int    increment;
                if (IncrementByName.TryGetValue(nonGenericNameWithNamespace, out increment) == true)
                {
                    if (fromProperty)
                    {
                        baseAffectedName = nonGenericName;
                    }
                    else
                    {
                        if (type.IsGenericParameter)
                        {
                            baseAffectedName = nonGenericName;
                        }
                        else
                        {
                            increment++;
                            baseAffectedName = $"{nonGenericName}{increment}";
                            IncrementByName[nonGenericNameWithNamespace] = increment;
                        }
                    }
                }
                else
                {
                    baseAffectedName = nonGenericName;
                    IncrementByName.Add(nonGenericNameWithNamespace, 0);
                }
                List <TypescriptType> typescriptTypeArguments = new List <TypescriptType>();
                Type[] argumentsOfType = null;
                if (type.GenericTypeArguments.Length > 0)
                {
                    argumentsOfType = type.GenericTypeArguments;
                }
                else if (type.GetTypeInfo().GenericTypeParameters.Length > 0)
                {
                    argumentsOfType = type.GetTypeInfo().GenericTypeParameters;
                }
                if (argumentsOfType != null)
                {
                    foreach (Type t in argumentsOfType)
                    {
                        typescriptTypeArguments.Add(AddType(t, fromProperty));
                    }

                    baseAffectedName += "<" + string.Join(",", typescriptTypeArguments.Select(x => x.QualifiedName(type.Namespace))) + ">";
                }


                if (type.IsArray)
                {
                    var typeOfArray = AddType(type.GetElementType(), fromProperty);
                    baseAffectedName = typeOfArray.QualifiedName(currentNamespace) + "[]";
                    typescriptType.AlwaysExcludeNamespace = true;
                }

                if (type.IsGenericType && typeof(Nullable <>).IsAssignableFrom(type.GetGenericTypeDefinition()))
                {
                    var typeOfArgument = AddType(type.GetGenericArguments()[0], fromProperty);
                    baseAffectedName = typeOfArgument.QualifiedName(currentNamespace);
                    typescriptType.AlwaysExcludeNamespace = true;
                }

                if (type.IsGenericType && (typeof(List <>).IsAssignableFrom(type.GetGenericTypeDefinition()) || typeof(IEnumerable <>).IsAssignableFrom(type.GetGenericTypeDefinition())))
                {
                    var typeOfArgument = AddType(type.GetGenericArguments()[0], fromProperty);
                    baseAffectedName = typeOfArgument.QualifiedName(currentNamespace) + "[]";
                    typescriptType.AlwaysExcludeNamespace = true;
                }

                if (type.IsGenericType && (
                        typeof(Dictionary <,>).IsAssignableFrom(type.GetGenericTypeDefinition()) ||
                        typeof(KeyValuePair <,>).IsAssignableFrom(type.GetGenericTypeDefinition()) ||
                        typeof(IDictionary <,>).IsAssignableFrom(type.GetGenericTypeDefinition())
                        )
                    )
                {
                    var genericArguments = type.GetGenericArguments();

                    if (genericArguments[0].Name == "String" || genericArguments[0].Name == "Int32")
                    {
                        var isInt = genericArguments[0].Name == "Int32";
                        var genericDictionaryArgument = AddType(genericArguments[1], fromProperty);
                        baseAffectedName = $"{{ [key: {(isInt ? "number" : "string")}]: {genericDictionaryArgument.QualifiedName(currentNamespace)} }}";
                    }
                    else
                    {
                        baseAffectedName = $"any/* because unsupported dictionary like key (only string or int32): {genericArguments[0].Name} */";
                    }
                    typescriptType.AlwaysExcludeNamespace = true;
                }

                if (type.IsGenericType && type.Name.StartsWith("Tuple`"))
                {
                    var tupleTab       = "\t";
                    var tupleArguments = type.GetGenericArguments();
                    var sbTuple        = new StringBuilder();
                    sbTuple.Append($"{{");
                    sbTuple.AppendLine($"");
                    for (var i = 0; i < tupleArguments.Length; i++)
                    {
                        var genericTupleArgument = AddType(tupleArguments[i], fromProperty);
                        sbTuple.AppendLine($"{tupleTab}Item{(i + 1)}: {genericTupleArgument.QualifiedName(currentNamespace)}{(i == (tupleArguments.Length - 1) ? "" : ",")}");
                    }
                    sbTuple.Append($"}}");
                    baseAffectedName = sbTuple.ToString();
                    typescriptType.AlwaysExcludeNamespace = true;
                }

                switch (type.Name.ToLowerInvariant())
                {
                case "datetime":
                case "guid":
                    baseAffectedName = "string";
                    typescriptType.AlwaysExcludeNamespace = true;
                    break;

                case "int16":
                case "int32":
                case "int64":
                case "uint16":
                case "uint32":
                case "uint64":
                case "single":
                case "double":
                case "decimal":
                    baseAffectedName = "number";
                    typescriptType.AlwaysExcludeNamespace = true;
                    break;

                case "boolean":
                    baseAffectedName = "boolean";
                    typescriptType.AlwaysExcludeNamespace = true;
                    break;

                case "object":
                    baseAffectedName = "any";
                    typescriptType.AlwaysExcludeNamespace = true;
                    break;

                case "void":
                case "string":
                    baseAffectedName = type.Name.ToLowerInvariant();
                    typescriptType.AlwaysExcludeNamespace = true;
                    break;
                }



                typescriptType.Type = baseAffectedName;
            }

            if (fromProperty)
            {
                typescriptType.TouchedInProperty = true;
            }
            return(typescriptType);
        }