Ejemplo n.º 1
0
        protected virtual void AppendEnumDefinition(TsEnum enumModel, ScriptBuilder sb, TsGeneratorOutput output)
        {
            string typeName   = this.GetTypeName(enumModel);
            string visibility = (output & TsGeneratorOutput.Enums) == TsGeneratorOutput.Enums || (output & TsGeneratorOutput.Constants) == TsGeneratorOutput.Constants ? "export " : "";

            _docAppender.AppendEnumDoc(sb, enumModel, typeName);

            string constSpecifier = this.GenerateConstEnums ? "const " : string.Empty;

            sb.AppendLineIndented(string.Format("{0}{2}enum {1} {{", visibility, typeName, constSpecifier));

            using (sb.IncreaseIndentation()) {
                int    i                = 1;
                string valuesList       = "";
                string descriptionsList = "";

                foreach (var v in enumModel.Values)
                {
                    _docAppender.AppendEnumValueDoc(sb, v);
                    bool appendComma = enumModel.IsOutputValuesList || enumModel.IsOutputDescriptionsList || (i < enumModel.Values.Count);
                    if (enumModel.IsValueAsStringOfName)
                    {
                        sb.AppendLineIndented(string.Format(appendComma ? "{0} = '{0}'," : "{0} = '{0}'", v.Name));
                        if (enumModel.IsOutputValuesList)
                        {
                            valuesList += string.Format((i < enumModel.Values.Count) ? "{0}|" : "{0}", v.Name);
                        }
                    }
                    else
                    {
                        sb.AppendLineIndented(string.Format(appendComma ? "{0} = {1}," : "{0} = {1}", v.Name, v.Value));
                        if (enumModel.IsOutputValuesList)
                        {
                            valuesList += string.Format(i < enumModel.Values.Count ? "{0}|" : "{0}", v.Value);
                        }
                    }
                    if (enumModel.IsOutputDescriptionsList)
                    {
                        descriptionsList += string.Format(i < enumModel.Values.Count ? "{0}|" : "{0}", v.Description);
                    }
                    i++;
                }
                if (enumModel.IsOutputValuesList)
                {
                    sb.AppendLineIndented(string.Format(enumModel.IsOutputDescriptionsList ? "_ValuesList = '{0}'," : "_ValuesList = '{0}'", valuesList));
                }
                if (enumModel.IsOutputDescriptionsList)
                {
                    sb.AppendLineIndented(string.Format("_DescriptionsList = '{0}'", descriptionsList));
                }
            }

            sb.AppendLineIndented("}");

            _generatedEnums.Add(enumModel);
        }
Ejemplo n.º 2
0
        public void WhenInitialized_NameIsSet()
        {
            var typeName = new TsBasicType()
            {
                Context = typeof(EnumWithoutAttribute), TypeName = "EnumWithoutAttribute"
            };
            var sut = new TsEnum(typeName);

            Assert.Same(typeName, sut.Name);
        }
Ejemplo n.º 3
0
        public void WhenInitialized_ValuesIsEmptyCollection()
        {
            var typeName = new TsBasicType()
            {
                Context = typeof(EnumWithoutAttribute), TypeName = "EnumWithoutAttribute"
            };
            var sut = new TsEnum(typeName);

            Assert.Empty(sut.Values);
        }
Ejemplo n.º 4
0
        public virtual string WriteEnum(TsEnum netEnum)
        {
            var enumStr   = string.Join("," + _config.NewLine, netEnum.Enums.Select(WriteEnumValue)).Indent(_indent);
            var exportStr = netEnum.IsPublic ? "export " : "";

            return($"{exportStr}enum {netEnum.Name}" + _config.NewLine +
                   @"{" + _config.NewLine +
                   $"{enumStr}" + _config.NewLine +
                   @"}");
        }
Ejemplo n.º 5
0
        public TsType GetType(Type clrType)
        {
            TsClass tsClass = null;

            if (Classes.TryGetValue(clrType, out tsClass))
            {
                return(tsClass);
            }

            TsEnum tsEnum = null;

            if (Enums.TryGetValue(clrType, out tsEnum))
            {
                return(tsEnum);
            }

            return(null);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Resolves TsType to the more specialized type.
        /// </summary>
        /// <param name="toResolve">The type to resolve.</param>
        /// <returns></returns>
        private TsType ResolveType(TsType toResolve, TsPropertyVisibilityFormatter propertyVisibilityFormatter, bool useOpenGenericDefinition = true)
        {
            if (!(toResolve is TsType))
            {
                return(toResolve);
            }

            if (_knownTypes.ContainsKey(toResolve.Type))
            {
                return(_knownTypes[toResolve.Type]);
            }
            else if (toResolve.Type.IsGenericType && useOpenGenericDefinition)
            {
                // We stored its open type definition instead
                TsType openType = null;
                if (_knownTypes.TryGetValue(toResolve.Type.GetGenericTypeDefinition(), out openType))
                {
                    return(openType);
                }
            }
            else if (toResolve.Type.IsGenericType)
            {
                var genericType = TsType.Create(toResolve.Type, propertyVisibilityFormatter);
                _knownTypes[toResolve.Type] = genericType;
                return(genericType);
            }

            var    typeFamily = TsType.GetTypeFamily(toResolve.Type);
            TsType type       = null;

            switch (typeFamily)
            {
            case TsTypeFamily.System: type = new TsSystemType(toResolve.Type); break;

            case TsTypeFamily.Collection: type = this.CreateCollectionType(toResolve, propertyVisibilityFormatter); break;

            case TsTypeFamily.Enum: type = new TsEnum(toResolve.Type); break;

            default: type = TsType.Any; break;
            }

            _knownTypes[toResolve.Type] = type;
            return(type);
        }
Ejemplo n.º 7
0
        protected override void AppendEnumDefinition(TsEnum enumModel, ScriptBuilder sb, TsGeneratorOutput output)
        {
            string typeName   = this.GetTypeName(enumModel);
            string visibility = ((output & TsGeneratorOutput.Enums) == TsGeneratorOutput.Enums || (output & TsGeneratorOutput.Constants) == TsGeneratorOutput.Constants) ? "export " : "";

            this._docAppender.AppendEnumDoc(sb, enumModel, typeName);
            string constSpecifier = this.GenerateConstEnums ? "const " : string.Empty;

            sb.AppendLineIndented(string.Format("{0}{2}enum {1} {{", visibility, typeName, constSpecifier));
            using (sb.IncreaseIndentation())
            {
                int i = 1;
                foreach (TsEnumValue v in enumModel.Values)
                {
                    this._docAppender.AppendEnumValueDoc(sb, v);
                    sb.AppendLineIndented(string.Format((i < enumModel.Values.Count) ? "{0} = {1}," : "{0} = {1}", ToCamelCase(v.Name), v.Value));
                    i++;
                }
            }
            sb.AppendLineIndented("}");
            this._generatedEnums.Add(enumModel);
        }
Ejemplo n.º 8
0
        protected override void AppendEnumDefinition(TsEnum enumModel, ScriptBuilder sb, TsGeneratorOutput output)
        {
            if (!AddNamespaceHeaderEnum(enumModel.Name, enumModel.Type.Assembly.FullName, sb))
            {
                return;
            }
            if (_typesToIgnore.Contains(enumModel.Type))
            {
                return;
            }

            var typeName   = this.GetTypeName(enumModel);
            var visibility = string.Empty;

            _docAppender.AppendEnumDoc(sb, enumModel, typeName);

            var constSpecifier = this.GenerateConstEnums ? "const " : string.Empty;

            sb.AppendLineIndented(string.Format("{0}{2}enum {1} {{", visibility, typeName, constSpecifier));

            using (sb.IncreaseIndentation())
            {
                var i = 1;
                foreach (var v in enumModel.Values)
                {
                    _docAppender.AppendEnumValueDoc(sb, v);
                    var enumMemberAttribute = v.Field.GetCustomAttribute <EnumMemberAttribute>();
                    var name = (!string.IsNullOrEmpty(enumMemberAttribute?.Value) ? enumMemberAttribute.Value : v.Name).QuoteMaybe();

                    sb.AppendLineIndented(string.Format(i < enumModel.Values.Count ? "{0} = {1}," : "{0} = {1}", name, v.Value));
                    i++;
                }
            }

            sb.AppendLineIndented("}");

            _generatedEnums.Add(enumModel);
        }
Ejemplo n.º 9
0
 public void AppendEnumDoc(ScriptBuilder sb, TsEnum enumModel, string enumName)
 {
 }
 protected override void AppendEnumDefinition(TsEnum enumModel, ScriptBuilder sb, TsGeneratorOutput output)
 {
     base.AppendEnumDefinition(enumModel, sb, TsGeneratorOutput.Enums);
 }
Ejemplo n.º 11
0
 private bool Ignore(TsEnum enumModel) => IsClrType(enumModel.Type);
Ejemplo n.º 12
0
 private static void AddContent(StringBuilder builder, string indententionString, TsEnum type)
 {
     builder.Append(indententionString);
     if (type.IsExport)
     {
         builder.Append("export ");
     }
     builder.Append($"enum {type.Name} " + "{");
     builder.AppendLine();
     builder.Append(string.Join($",{Environment.NewLine}", type.Values.Select(x => $"{indententionString}\t{GenerateContent(x)}")));
     builder.AppendLine();
     builder.Append(indententionString + "}");
 }
Ejemplo n.º 13
0
        /// <summary>
        /// Resolves TsType to the more specialized type.
        /// </summary>
        /// <param name="toResolve">The type to resolve.</param>
        /// <returns></returns>
        private TsType ResolveType(TsType toResolve, bool useOpenGenericDefinition = true)
        {
            if (!(toResolve is TsType)) {
                return toResolve;
            }

            if (_knownTypes.ContainsKey(toResolve.Type)) {
                return _knownTypes[toResolve.Type];
            } else if (toResolve.Type.IsGenericType && useOpenGenericDefinition) {
                // We stored its open type definition instead
                TsType openType = null;
                if (_knownTypes.TryGetValue(toResolve.Type.GetGenericTypeDefinition(), out openType)) {
                    return openType;
                }
            } else if (toResolve.Type.IsGenericType) {
                var genericType = TsType.Create(toResolve.Type);
                _knownTypes[toResolve.Type] = genericType;
                return genericType;
            }

            var typeFamily = TsType.GetTypeFamily(toResolve.Type);
            TsType type = null;

            switch (typeFamily) {
                case TsTypeFamily.System: type = new TsSystemType(toResolve.Type); break;
                case TsTypeFamily.Collection: type = this.CreateCollectionType(toResolve); break;
                case TsTypeFamily.Enum: type = new TsEnum(toResolve.Type); break;
                default: type = TsType.Any; break;
            }

            _knownTypes[toResolve.Type] = type;
            return type;
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Adds type and optionally referenced classes to the model.
        /// </summary>
        /// <param name="clrType">The type to add to the model.</param>
        /// <param name="includeReferences">bool value indicating whether classes referenced by T should be added to the model.</param>
        /// <returns>type added to the model</returns>
        public TsModuleMember Add(Type clrType, bool includeReferences, Dictionary <Type, TypeConvertor> typeConvertors = null)
        {
            var typeFamily = TsType.GetTypeFamily(clrType);

            if (typeFamily != TsTypeFamily.Class && typeFamily != TsTypeFamily.Enum)
            {
                throw new ArgumentException(string.Format("Type '{0}' isn't class or struct. Only classes and structures can be added to the model", clrType.FullName));
            }

            if (clrType.IsNullable())
            {
                return(this.Add(clrType.GetNullableValueType(), includeReferences, typeConvertors));
            }

            if (typeFamily == TsTypeFamily.Enum)
            {
                var enumType = new TsEnum(clrType);
                this.AddEnum(enumType);
                return(enumType);
            }

            if (clrType.IsGenericType)
            {
                if (!this.Classes.ContainsKey(clrType))
                {
                    var openGenericType = clrType.GetGenericTypeDefinition();
                    var added           = new TsClass(openGenericType);
                    this.Classes[openGenericType] = added;
                    if (includeReferences)
                    {
                        this.AddReferences(added, typeConvertors);

                        foreach (var e in added.Properties.Where(p => p.PropertyType.Type.IsEnum))
                        {
                            this.AddEnum(e.PropertyType as TsEnum);
                        }
                    }
                }
            }

            if (!this.Classes.ContainsKey(clrType))
            {
                var added = new TsClass(clrType);
                this.Classes[clrType] = added;
                if (clrType.IsGenericParameter)
                {
                    added.IsIgnored = true;
                }
                if (clrType.IsGenericType)
                {
                    added.IsIgnored = true;
                }

                if (added.BaseType != null)
                {
                    this.Add(added.BaseType.Type);
                }
                if (includeReferences)
                {
                    this.AddReferences(added, typeConvertors);

                    foreach (var e in added.Properties.Where(p => p.PropertyType.Type.IsEnum))
                    {
                        this.AddEnum(e.PropertyType as TsEnum);
                    }
                }

                foreach (var @interface in added.Interfaces)
                {
                    this.Add(@interface.Type);
                }

                return(added);
            }
            else
            {
                return(this.Classes[clrType]);
            }
        }
        public void WhenInitialized_NameIsSet()
        {
            var target = new TsEnum(typeof(ContactType));

            Assert.Equal("ContactType", target.Name);
        }
Ejemplo n.º 16
0
 /// <summary>
 /// When overridden in a derived class, it can examine or modify the enum model.
 /// </summary>
 /// <param name="enumModel">The model enum being visited.</param>
 public virtual void VisitEnum(TsEnum enumModel)
 {
 }
Ejemplo n.º 17
0
 /// <summary>
 /// When overridden in a derived class, it can examine or modify the enum model.
 /// </summary>
 /// <param name="enumModel">The model enum being visited.</param>
 public virtual void VisitEnum(TsEnum enumModel)
 {
 }
Ejemplo n.º 18
0
 public void AppendEnumDoc(ScriptBuilder sb, TsEnum enumModel, string enumName)
 {
     AppendModelDoc(sb, enumModel.Type);
 }
Ejemplo n.º 19
0
 private TsEnum GenerateEnum(Type type)
 {
     var names = type.GetEnumNames();
     var values = type.GetEnumValues();
     var entries = new Dictionary<string, long?>();
     for (int i = 0; i < values.Length; i++)
         entries.Add(names[i], Convert.ToInt64(values.GetValue(i)));
     var tsEnum = new TsEnum(GetName(type), entries);
     this.TypeLookup.Add(type, tsEnum);
     return tsEnum;
 }
Ejemplo n.º 20
0
 /// <summary>
 /// Resolves references in the enum.
 /// </summary>
 /// <param name="enumModel"></param>
 public override void VisitEnum(TsEnum enumModel)
 {
     if (enumModel.Module != null) {
         enumModel.Module = this.ResolveModule(enumModel.Module.Name);
     }
 }
Ejemplo n.º 21
0
 public void AppendEnumDoc(ScriptBuilder sb, TsEnum enumModel, string enumName)
 {
     AppendModelDoc(sb, enumModel.Type);
 }
Ejemplo n.º 22
0
        public void WhenInitialized_NameIsSet()
        {
            var target = new TsEnum(typeof(ContactType));

            Assert.Equal("ContactType", target.Name);
        }
Ejemplo n.º 23
0
 public void AppendEnumDoc(ScriptBuilder sb, TsEnum enumModel, string enumName)
 {
 }
Ejemplo n.º 24
0
        public ParameterResolution(IParameterSymbol parameterSymbol, TypeResolver typeResolver, ResolutionContext context, Options options)
        {
            var p    = parameterSymbol;
            var type = p.Type;
            //it it is generic type, try get some constraint type
            var cTypes = (type as ITypeParameterSymbol)?.ConstraintTypes;

            if (cTypes.HasValue)
            {
                type = cTypes.Value.First();
            }

            var attrs = p.GetAttributes();

            //Removing tuple support...it' not worth it
            //var hasNamedTupleAttr = attrs.Any(a => a.AttributeClass.Name == nameof(NamedTupleAttribute));
            var res = typeResolver.Resolve(type, context /*, hasNamedTupleAttr*/);

            this.Name              = p.Name;
            this.FromName          = p.Name;
            this.SearchRelayFormat = this.Name;
            var fromAttr = attrs.FirstOrDefault(a => a.AttributeClass.Name.StartsWith("From"));

            //
            if (fromAttr != null)
            {
                switch (fromAttr.AttributeClass.Name)
                {
                case "FromUriAttribute":
                case "FromQueryAttribute":
                case "FromBodyAttribute":
                case "FromRouteAttribute":
                    this.From = (ParameterFromKind)typeof(ParameterFromKind).GetField(fromAttr.AttributeClass.Name.Replace("Attribute", "")).GetValue(null);
                    switch (fromAttr.AttributeClass.Name)
                    {
                    case "FromUriAttribute":
                    case "FromQueryAttribute":
                        KeyValuePair <string, TypedConstant>?nameArg = fromAttr.NamedArguments.ToList().FirstOrDefault(na => na.Key == "Name");
                        if (nameArg.HasValue)
                        {
                            var tConst = nameArg.Value.Value;
                            if (tConst.Value != null)
                            {
                                this.FromName          = tConst.Value.ToString();
                                this.SearchRelayFormat = $"{this.FromName}: {this.Name}";
                            }
                        }
                        break;
                    }

                    break;
                }
            }

            //Check if it is a Model being used to catch query/route parameters
            if (type.IsReferenceType)
            {
                var            props            = new List <string>();
                var            outProps         = new List <string>();
                var            hasModifications = false;
                List <ISymbol> members          = new List <ISymbol>();
                var            t = type;
                while (t != null)
                {
                    members.AddRange(t.GetMembers());
                    t = t.BaseType;
                }

                foreach (var m in members)
                {
                    if (m.Kind != SymbolKind.Field && m.Kind != SymbolKind.Property)
                    {
                        continue;
                    }
                    if (m.DeclaredAccessibility != Accessibility.Public)
                    {
                        continue;
                    }
                    if (((m as IFieldSymbol)?.IsConst).GetValueOrDefault())
                    {
                        continue;
                    }
                    var name = m.Name;
                    if (!options.KeepPropsCase && !((m as IFieldSymbol)?.IsConst).GetValueOrDefault())
                    {
                        name = name.ToCamelCase();
                    }
                    if (m is IPropertySymbol)
                    {
                        //allProps.Add(m.Name);
                        var propAttrs    = m.GetAttributes();
                        var propFromAttr = propAttrs.FirstOrDefault(a => a.AttributeClass.Name.StartsWith("From"));
                        if (propFromAttr != null)
                        {
                            switch (propFromAttr.AttributeClass.Name)
                            {
                            case "FromRouteAttribute":
                                hasModifications = true;
                                //ignoredQueryProps.Add(m.Name);
                                break;

                            case "FromUriAttribute":
                            case "FromQueryAttribute":
                                KeyValuePair <string, TypedConstant>?nameArg = propFromAttr.NamedArguments.ToList().FirstOrDefault(na => na.Key == "Name");
                                if (nameArg.HasValue)
                                {
                                    var tConst = nameArg.Value.Value;
                                    if (tConst.Value != null)
                                    {
                                        //renamedQueryProps.Add(p.Name, tConst.Value.ToString());
                                        outProps.Add($"{tConst.Value.ToString()}: {this.Name}.{name}");
                                        hasModifications = true;
                                    }
                                }
                                break;

                            default:
                                props.Add($"{name}: {this.Name}.{name}");
                                break;
                            }
                        }
                        else
                        {
                            props.Add($"{name}: {this.Name}.{name}");
                        }
                    }
                }

                if (hasModifications)
                {
                    this.SearchRelayFormat = "";
                    if (props.Any())
                    {
                        //Pensar melhor, no asp.net podemos colocar como parametros varias models com props de nomes iguais.
                        //Por esse motivo fazemos o obj: {}
                        //Ao mesmo tempo, isso é uma modelagem esquisita de api. Talvez devemos dar preferencia mesmo para a segunda opção
                        //onde fica tudo na "raiz". Além disso, não testei ainda o comportamento do asp.net quando multiplos parametros
                        //que clasheiam sujas props
                        //O maior motivo, é que no caso de uma model que possui alguns itens na raiz, ficando ora model.coisa e $coisa2
                        //por ex, o asp.net se perde em seu modelbinding, considerando apenas no model.<algo>.
                        //this.SearchRelayFormat = $"...({this.Name} ? {{ {this.FromName}: {{ {string.Join(", ", props)} }} }} : {{}})";
                        this.SearchRelayFormat = $"...({this.Name} ? {{ {string.Join(", ", props)} }} : {{}})";
                    }
                    if (outProps.Any())
                    {
                        if (props.Any())
                        {
                            //Add comma
                            this.SearchRelayFormat += ", ";
                        }
                        this.SearchRelayFormat += $"...({this.Name} ? {{{string.Join(", ", outProps)}}} : {{}})";
                    }
                }
            }


            string typeName = res.Declaration;

            if (TsEnum.IsEnum(type))
            {
                if (res.IsEnum)
                {
                    var enumNames = string
                                    .Join(
                        " | ",
                        type.GetMembers()
                        .Where(m => m.Kind == SymbolKind.Field)
                        .Select(m => $"'{m.Name}'"));
                    if (!string.IsNullOrEmpty(enumNames))
                    {
                        typeName = $"{typeName} | {enumNames}";
                    }
                }
            }

            this.Type       = res;
            this.IsOptional = p.IsOptional;
            this.Signature  = $"{p.Name}{(p.IsOptional ? "?" : "")}: {typeName}" + (res.IsNullable ? " | null" : "");
            this.Ignore     = p.GetAttributes().Any(a => a.AttributeClass.Name == "FromServices");
        }
Ejemplo n.º 25
0
 public virtual string Format(TsEnum tsEnum)
 {
     using (var sbc = new StringBuilderContext(this))
     {
         this.WriteIndent();
         this.Write("enum {0} {{", Format(tsEnum.Name));
         this.WriteNewline();
         using (Indent())
         {
             var values = tsEnum.Values.ToArray();
             for (int i = 0; i < values.Length; i++)
             {
                 var postFix = i < values.Length - 1 ? "," : string.Empty;
                 var entry = values[i];
                 this.WriteIndent();
                 if (entry.Value.HasValue)
                     this.Write("{0} = {1}{2}", entry.Key, entry.Value, postFix);
                 else
                     this.Write("{0}{1}", entry.Key, postFix);
                 this.WriteNewline();
             }
         }
         this.WriteIndent();
         this.Write("}");
         this.WriteNewline();
         return sbc.ToString();
     }
 }
 public void AppendEnumDoc(IndentedStringBuilder sb, TsEnum enumModel, string enumName)
 {
 }
Ejemplo n.º 27
0
        async Task <TypeResolver> PrepareAsync()
        {
            var trees = _trees.ToList();
            //TODO: Temp workaround.. investigate why referencing annotations assembly is nor working properly
            var attributes = CSharpSyntaxTree.ParseText(@"
using System;

namespace WebTyped.Annotations {
	[AttributeUsage(AttributeTargets.Class)]
	public class ClientTypeAttribute : Attribute {
		public ClientTypeAttribute(string typeName = null, string module = null) {}
	}
	[AttributeUsage(AttributeTargets.Parameter)]
	public class NamedTupleAttribute : Attribute {
		public NamedTupleAttribute() {}
	}
}

namespace System.Web.Http {
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false)]
	public class FromUriAttribute : Attribute {
		public string Name { get; set; }
		public Type BinderType { get; set; }
		public bool SuppressPrefixCheck { get; set; }
	}

	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false)]
	public class FromBodyAttribute : Attribute {}
}

namespace Microsoft.AspNetCore.Mvc{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false)]
	public class FromQueryAttribute : Attribute {
		public string Name { get; set; }
	}

	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false)]
	public class FromRouteAttribute : Attribute {
		public string Name { get; set; }
	}

	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false)]
	public class FromBodyAttribute : Attribute {}
}
");
            //References
            var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
            //var webTypedAnnotations = MetadataReference.CreateFromFile(typeof(ClientTypeAttribute).Assembly.Location);
            var systemRuntime   = MetadataReference.CreateFromFile(typeof(int).Assembly.Location);
            var linqExpressions = MetadataReference.CreateFromFile(typeof(IQueryable).Assembly.Location);
            //Nullable
            var thisAssembly = MetadataReference.CreateFromFile(this.GetType().Assembly.Location);

            //External assemblies
            var externals = new List <PortableExecutableReference>();

            foreach (var path in assemblies)
            {
                if (File.Exists(path))
                {
                    externals.Add(MetadataReference.CreateFromFile(path));
                }
            }

            //var nugetGlobalPackages = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
            //     ? "%userprofile%/.nuget/packages"
            //     : "~/.nuget/packages";
            if (packages.Any())
            {
                //Finding nuget global-packages
                //var process = Process.Start("dotnet", "nuget locals global-packages --list");
                //process.BeginOutputReadLine();
                Process process = new Process
                {
                    StartInfo =
                    {
                        FileName               = "dotnet",
                        Arguments              = "nuget locals global-packages --list",
                        UseShellExecute        = false,
                        RedirectStandardOutput = true,
                        RedirectStandardError  = true,
                        CreateNoWindow         = true
                    }
                };
                string globalPackagePath = "";
                process.EnableRaisingEvents = true;
                process.OutputDataReceived += (s, e) => {
                    if (string.IsNullOrWhiteSpace(globalPackagePath))
                    {
                        globalPackagePath = e.Data;
                    }
                };
                process.ErrorDataReceived += (s, e) => Debug.WriteLine($@"Error: {e.Data}");
                process.Start();
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();
                process.WaitForExit();
                globalPackagePath = globalPackagePath.Replace("info : global-packages: ", "");

                if (string.IsNullOrWhiteSpace(globalPackagePath))
                {
                    Console.WriteLine($"Nuget global-packages not found");
                }
                else
                {
                    foreach (var pkg in packages)
                    {
                        if (string.IsNullOrWhiteSpace(pkg.Version) && string.IsNullOrWhiteSpace(pkg.Csproj))
                        {
                            throw new Exception($"{pkg.Name} version not informed");
                        }

                        var version = pkg.Version;
                        if (!string.IsNullOrWhiteSpace(pkg.Csproj))
                        {
                            var reference = XDocument
                                            .Load(pkg.Csproj)
                                            .Descendants()
                                            .FirstOrDefault(d => d.Name.LocalName == "PackageReference" && d.Attribute("Include").Value == pkg.Name);

                            if (reference != null)
                            {
                                version = reference.Attribute("Version").Value;
                            }
                        }



                        //var nugetGlobalPackages = $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/.nuget/packages";
                        var pkgDir = $"{globalPackagePath}{pkg.Name}/{version}".ToLower();

                        if (!Directory.Exists(pkgDir))
                        {
                            Console.WriteLine($"Package {pkg.Name} not found in {pkgDir}");
                            continue;
                        }

                        var dllPaths = Directory.GetFiles(pkgDir, $"*.dll", SearchOption.AllDirectories);
                        var grouped  = dllPaths.GroupBy(path => Path.GetFileName(path));
                        foreach (var g in grouped)
                        {
                            externals.Add(MetadataReference.CreateFromFile(g.First()));
                        }

                        //if(dllPath != null)
                        //{
                        //    externals.Add(MetadataReference.CreateFromFile(dllPath));
                        //}
                    }
                }
            }

            var compilation = CSharpCompilation.Create(
                "Comp",
                //Trees
                trees
                .Union(new SyntaxTree[] { attributes })
                ,
                //basic + external Assemblies
                new[] {
                mscorlib,
                systemRuntime,
                linqExpressions,
                //MetadataReference.CreateFromFile(typeof(Attribute).Assembly.Location),
                //thisAssembly
                /*, webTypedAnnotations*/
            }
                .Union(externals)
                );
            var typeResolver     = new TypeResolver(_options);
            var tasks            = new List <Task>();
            var namedTypeSymbols = new ConcurrentBag <INamedTypeSymbol>();
            var semanticModels   = trees.ToDictionary(t => t, t => compilation.GetSemanticModel(t));

            foreach (var t in trees)
            {
                tasks.Add(t.GetRootAsync().ContinueWith(tks =>
                {
                    var root = tks.Result;
                    foreach (var @type in root.DescendantNodes().OfType <BaseTypeDeclarationSyntax>())
                    {
                        var sm = semanticModels[t];
                        namedTypeSymbols.Add(sm.GetDeclaredSymbol(@type));
                    }
                }));
            }

            //Types in referenced assemblies
            var assembliesTypesMatcher = new Matcher();

            referenceTypes.ToList().ForEach(t => assembliesTypesMatcher.AddInclude(t));
            //var allSymbols = compilation.GetSymbolsWithName((str) => true);


            foreach (var e in externals)
            {
                //var ass = Assembly.ReflectionOnlyLoadFrom(Path.GetFullPath(e.FilePath));
                var assSymbol = compilation.GetAssemblyOrModuleSymbol(e) as IAssemblySymbol;

                //var tm = assSymbol.GlobalNamespace.GetTypeMembers();
                var named = GetNamedTypeSymbols(assSymbol.GlobalNamespace);// assSymbol.GlobalNamespace.GetMembers().OfType<INamedTypeSymbol>();
                //var fullNames = named.Select(n => n.ToString().Split(" ").Last());
                foreach (var n in named)
                {
                    try
                    {
                        var fullName = n.ToString().Split(" ").Last();
                        if (assembliesTypesMatcher.Match(fullName).HasMatches)
                        {
                            namedTypeSymbols.Add(n);
                        }
                    }
                    catch { }
                }

                //foreach(var fn in fullNames)
                //{
                //    try
                //    {
                //        if (assembliesTypesMatcher.Match(fn).HasMatches)
                //        {
                //            var name = fn;

                //            var nts = assSymbol.GetTypeByMetadataName(name);
                //            namedTypeSymbols.Add(nts);
                //        }
                //    }
                //    catch { }
                //}

                //var named = assSymbol.GlobalNamespace.GetMembers().OfType<INamedTypeSymbol>();

                //var typeNames = ass.GetTypes().Select(t => t.FullName);

                //foreach(var tn in typeNames)
                //{
                //    try
                //    {
                //        if (assembliesTypesMatcher.Match(tn).HasMatches)
                //        {
                //            namedTypeSymbols.Add(assSymbol.GetTypeByMetadataName(tn));
                //        }
                //    }
                //    catch { }
                //}
            }



            foreach (var tsk in tasks)
            {
                await tsk;
            }
            foreach (var s in namedTypeSymbols)
            {
                if (Service.IsService(s))
                {
                    typeResolver.Add(new Service(s, typeResolver, _options));
                    continue;
                }

                if (Model.IsModel(s))
                {
                    typeResolver.Add(new Model(s, typeResolver, _options));
                    continue;
                }

                if (TsEnum.IsEnum(s))
                {
                    typeResolver.Add(new TsEnum(s, typeResolver, _options));
                    continue;
                }
            }
            return(typeResolver);
        }
Ejemplo n.º 28
0
        private void MapToTsType(Type type)
        {
            if (mTypeToTsTypeMap.ContainsKey(type))
            {
                return;
            }
            var foundMapping = mAllMappings.FirstOrDefault(m => m.MatchesType.Invoke(type));

            if (foundMapping != null)
            {
                mTypeToTsTypeMap[type] = new TsMappedType(foundMapping.DestinationType, foundMapping.DestinationAssignmentTemplate);
            }
            else
            {
                Type itemType;
                Type keyItemType;
                Type valueItemType;

                if (IsDictionary(type, out keyItemType, out valueItemType))
                {
                    MapToTsType(keyItemType);
                    MapToTsType(valueItemType);
                    mTypeToTsTypeMap[type] = new TsDictionary(mTypeToTsTypeMap[keyItemType], mTypeToTsTypeMap[valueItemType]);
                }
                else if (IsIEnumerableType(type, out itemType))
                {
                    MapToTsType(itemType);
                    mTypeToTsTypeMap[type] = new TsCollection(mTypeToTsTypeMap[itemType]);
                }
                else if (type.IsEnum)
                {
                    var enumType    = new TsEnum(type.Namespace, type.Name);
                    var names       = Enum.GetNames(type);
                    var valuesArray = Enum.GetValues(type);
                    var values      = valuesArray.Cast <object>().Select(v => Convert.ToInt64(v)).ToArray();
                    for (int i = 0; i < names.Length; i++)
                    {
                        enumType.Members.Add(new KeyValuePair <string, long>(names[i], values[i]));
                    }
                    mTypeToTsTypeMap[type] = enumType;
                }
                // nullable enum
                else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>) &&
                         type.GetGenericArguments()[0].IsEnum)
                {
                    var enumType    = new TsEnum(type.GetGenericArguments()[0].Namespace, type.GetGenericArguments()[0].Name);
                    var names       = Enum.GetNames(type.GetGenericArguments()[0]);
                    var valuesArray = Enum.GetValues(type.GetGenericArguments()[0]);
                    var values      = valuesArray.Cast <object>().Select(v => Convert.ToInt64(v)).ToArray();
                    for (int i = 0; i < names.Length; i++)
                    {
                        enumType.Members.Add(new KeyValuePair <string, long>(names[i], values[i]));
                    }
                    mTypeToTsTypeMap[type] = enumType;
                }
                else
                {
                    // Check if current TypeWithProperties has a base class that is not object
                    TsType baseTsType = null;
                    if (type.IsClass && type != typeof(Object) && type.BaseType != typeof(Object))
                    {
                        MapToTsType(type.BaseType);
                        baseTsType = mTypeToTsTypeMap[type.BaseType];
                    }

                    var tsType = new TsTypeWithProperties(type.Namespace, type.Name, baseTsType);
                    mTypeToTsTypeMap[type] = tsType;

                    var propertyInfos = type
                                        .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)
                                        .Where(p => p.GetMethod.IsPublic && !p.GetMethod.GetParameters().Any());

                    // iterate properties.
                    foreach (var prop in propertyInfos)
                    {
                        MapToTsType(prop.PropertyType);
                        tsType.Properties.Add(new TsProperty {
                            Name = prop.Name, TsType = mTypeToTsTypeMap[prop.PropertyType]
                        });
                    }
                }
            }
        }