private void WriteInterfaceNode(TypeScriptBlock interfacesBlock, InterfaceNode interfaceNode)
        {
            var typeDefinition = interfaceNode.TypeDefinition;

            string implementsString = null;
            string extendsString    = null;

            var iHaveGenericParameters = typeDefinition.HasGenericParameters;

            if (iHaveGenericParameters)
            {
                var genericParameters = typeDefinition.GenericParameters
                                        .Select(p => p.Name);

                implementsString = WrapInAngledBrackets(string.Join(", ", genericParameters));
            }

            var hasBaseClass = interfaceNode.BaseInterface?.TypeDefinition != null;
            var baseTypeName = CleanName(interfaceNode.BaseInterface?.TypeDefinition?.Name);

            if (hasBaseClass)
            {
                var iHaveGenericArguments = typeDefinition.BaseType.IsGenericInstance;
                if (iHaveGenericArguments)
                {
                    var baseTypeInstance = typeDefinition.BaseType as GenericInstanceType;
                    var genericArguments = baseTypeInstance.GenericArguments
                                           .Select(p => p.IsGenericParameter
                            ? p.Name
                            : TypeService.GetTypeScriptType(p.GetElementType(), p.Name).TypeName);

                    extendsString = WrapInAngledBrackets(string.Join(", ", genericArguments));
                }

                var baseTypeHasGenericParameters = typeDefinition.BaseType.HasGenericParameters;
                if (baseTypeHasGenericParameters)
                {
                    var genericParameters = typeDefinition.BaseType.GenericParameters
                                            .Select(p => p.Name);

                    extendsString = WrapInAngledBrackets(string.Join(", ", genericParameters));
                }
            }

            var interfaceExtendsString = hasBaseClass
                ? $" extends I{baseTypeName}{extendsString}"
                : string.Empty;

            var classExtendsString = hasBaseClass
                ? $" extends {baseTypeName}{extendsString}"
                : string.Empty;

            var blockTypeName = CleanName(typeDefinition.Name);

            if (!TypeService.IsValidTypeName(blockTypeName))
            {
                LogMessage($"Interface name [{blockTypeName}] of type [{typeDefinition.FullName}] is invalid!");
                return;
            }

            var classImplementsString =
                $" implements I{blockTypeName}{implementsString}";

            var parameterOrInstanceString = iHaveGenericParameters
                ? implementsString
                : string.Empty;

            var interfaceBlock = interfacesBlock
                                 .AddAndUseBlock($"export interface I{blockTypeName}{parameterOrInstanceString}{interfaceExtendsString}");

            TypeScriptBlock classBlock = null;

            if (Config.GenerateInterfaceClasses)
            {
                classBlock = interfacesBlock
                             .AddAndUseBlock($"export class {blockTypeName}{parameterOrInstanceString}{classExtendsString}{classImplementsString}");
            }

            var things = GetMembers(typeDefinition);

            foreach (var thing in things)
            {
                var thingType = thing.CSharpType.TypeDefinition;

                var union = SameNamedDerivedMembers(thing, interfaceNode)
                            .Select(e => e.CSharpType.TypeDefinition)
                            .ToList();

                union.Add(thingType);

                string interfaceName;
                string typeName;
                if (thing.CSharpType.IsGenericParameter)
                {
                    typeName = interfaceName = thing.CSharpType.GenericParameterName;
                }
                else
                {
                    if (thingType.IsInterface)
                    {
                        continue;
                    }

                    if (union.Count == 1)
                    {
                        var typeScriptType = TypeService.GetTypeScriptType(union[0], thing.Name);

                        interfaceName = typeScriptType.InterfaceName;
                        typeName      = typeScriptType.TypeName;
                    }
                    else
                    {
                        typeName = string.Join(" | ", union
                                               .Select(t =>
                        {
                            var type = TypeService.GetTypeScriptType(t, thing.Name);
                            return(type.TypeName);
                        })
                                               .Distinct());

                        interfaceName = string.Join(" | ", union
                                                    .Select(t =>
                        {
                            var type = TypeService.GetTypeScriptType(t, thing.Name);
                            return(type.InterfaceName);
                        }).Distinct());
                    }
                }

                var thingName = Config.InterfaceMembersInCamelCase
                    ? Helpers.ToCamelCaseFromPascalCase(thing.Name)
                    : thing.Name;

                var collectionString = thing.CSharpType.IsCollection ? "[]" : string.Empty;

                thingName = TypeService.FixIfReservedWord(thingName);

                interfaceBlock
                .AddStatement($"{thingName}: {interfaceName}{collectionString};");

                if (Config.GenerateInterfaceClasses)
                {
                    classBlock
                    .AddStatement($"{thingName}: {typeName}{collectionString};");
                }
            }

            if (Config.GenerateInterfaceClasses)
            {
                if (hasBaseClass)
                {
                    classBlock
                    .AddAndUseBlock("constructor()")
                    .AddStatement("super();");
                }
            }
        }
示例#2
0
        private void WriteInterfaceNode(TypeScriptBlock interfacesBlock, InterfaceNode interfaceNode)
        {
            var typeDefinition = interfaceNode.TypeDefinition;

            string implementsString = null;

            string _interfaceExtendsString = null;
            string _classExtendsString     = null;

            var iHaveGenericParameters = typeDefinition.HasGenericParameters;

            if (iHaveGenericParameters)
            {
                var genericParameters = typeDefinition.GenericParameters
                                        .Select(p => p.Name);

                implementsString = WrapInAngledBrackets(string.Join(", ", genericParameters));
            }

            var hasBaseClass = interfaceNode.BaseInterface?.TypeDefinition != null;
            var baseTypeName = TypeService.CleanGenericName(interfaceNode.BaseInterface?.TypeDefinition?.Name);
            var things       = GetMembers(typeDefinition);

            if (hasBaseClass)
            {
                if (typeDefinition.BaseType is GenericInstanceType baseTypeInstance)
                {
                    var classGenericArguments = baseTypeInstance.GenericArguments
                                                .Select(p => p.IsGenericParameter
                            ? p.Name
                            : TypeService.GetTypeScriptType(p.GetElementType(), p.Name).TypeName);

                    var interfaceGenericArguments = baseTypeInstance.GenericArguments
                                                    .Select(p => p.IsGenericParameter
                            ? p.Name
                            : TypeService.GetTypeScriptType(p.GetElementType(), p.Name).InterfaceName);

                    _classExtendsString     = WrapInAngledBrackets(string.Join(", ", classGenericArguments));
                    _interfaceExtendsString = WrapInAngledBrackets(string.Join(", ", interfaceGenericArguments));
                }
                else
                {
                    var baseTypeHasGenericParameters = typeDefinition.BaseType.HasGenericParameters;
                    if (baseTypeHasGenericParameters)
                    {
                        var genericParameters = typeDefinition.BaseType.GenericParameters
                                                .Select(p => p.Name);

                        _classExtendsString = _interfaceExtendsString = WrapInAngledBrackets(string.Join(", ", genericParameters));
                    }
                }
            }

            var interfaceExtendsString = hasBaseClass
                ? $" extends I{baseTypeName}{_interfaceExtendsString}"
                : string.Empty;

            var classExtendsString = hasBaseClass
                ? $" extends {baseTypeName}{_classExtendsString}"
                : string.Empty;

            var blockTypeName = TypeService.CleanGenericName(typeDefinition.Name);

            if (!TypeService.IsValidTypeName(blockTypeName))
            {
                LogMessage($"Interface name [{blockTypeName}] of type [{typeDefinition.FullName}] is invalid!");
                return;
            }

            var classImplementsString =
                $" implements I{blockTypeName}{implementsString}";

            var parameterOrInstanceString = iHaveGenericParameters
                ? implementsString
                : string.Empty;

            var interfaceBlock = interfacesBlock
                                 .AddAndUseBlock($"export interface I{blockTypeName}{parameterOrInstanceString}{interfaceExtendsString}");

            TypeScriptBlock classBlock = null;

            if (Config.GenerateInterfaceClasses)
            {
                classBlock = interfacesBlock
                             .AddAndUseBlock($"export class {blockTypeName}{parameterOrInstanceString}{classExtendsString}{classImplementsString}");
            }

            foreach (var thing in things)
            {
                var thingType = thing.CSharpType.TypeDefinition;

                var union = SameNamedDerivedMembers(thing, interfaceNode)
                            .Select(e => e.CSharpType.TypeDefinition)
                            .ToList();

                union.Add(thingType);

                string interfaceName;
                string typeName;
                if (thing.CSharpType.IsGenericParameter)
                {
                    typeName = interfaceName = thing.CSharpType.GenericParameterName;
                }
                else if (thing.CSharpType.IsGenericInstance)
                {
                    var baseTypeScriptType = TypeService.GetTypeScriptType(thing.CSharpType.TypeDefinition, thing.Name);

                    if (baseTypeScriptType.IsMappedType)
                    {
                        typeName      = baseTypeScriptType.TypeName;
                        interfaceName = baseTypeScriptType.InterfaceName;
                    }
                    else
                    {
                        var typeNames = string.Join(", ", thing.CSharpType.GenericArgumentTypes
                                                    .Select(t =>
                        {
                            var genericArgumentTypeScriptType = TypeService.GetTypeScriptType(t, thing.Name);
                            return(genericArgumentTypeScriptType.TypeName);
                        }));

                        var interfaceNames = string.Join(", ", thing.CSharpType.GenericArgumentTypes
                                                         .Select(t =>
                        {
                            var genericArgumentTypeScriptType = TypeService.GetTypeScriptType(t, thing.Name);
                            return(genericArgumentTypeScriptType.InterfaceName);
                        }));

                        typeName      = $"{baseTypeScriptType.TypeName}<{typeNames}>";
                        interfaceName = $"{baseTypeScriptType.InterfaceName}<{interfaceNames}>";
                    }
                }
                else
                {
                    if (thingType.IsInterface)
                    {
                        continue;
                    }

                    if (union.Count == 1)
                    {
                        var typeScriptType = TypeService.GetTypeScriptType(union[0], thing.Name);

                        typeName      = typeScriptType.TypeName;
                        interfaceName = typeScriptType.InterfaceName;
                    }
                    else
                    {
                        typeName = string.Join(" | ", union
                                               .Select(t =>
                        {
                            var type = TypeService.GetTypeScriptType(t, thing.Name);
                            return(type.TypeName);
                        })
                                               .Distinct());

                        interfaceName = string.Join(" | ", union
                                                    .Select(t =>
                        {
                            var type = TypeService.GetTypeScriptType(t, thing.Name);
                            return(type.InterfaceName);
                        }).Distinct());
                    }
                }

                var thingName = thing.Name;

                var jsonProperty = thing.CustomAttributes.SingleOrDefault(a => a.AttributeType.Name == "JsonPropertyAttribute");

                if (jsonProperty != null)
                {
                    try
                    {
                        thingName = jsonProperty?.HasProperties ?? false
                            ? jsonProperty.Properties.Single(p => p.Name == "PropertyName").Argument.Value.ToString()
                            : jsonProperty?.HasConstructorArguments ?? false
                                ? jsonProperty.ConstructorArguments.Single().Value.ToString()
                                : thing.Name;
                    }
                    catch
                    {
                        // This is to suppress a assembly load execption which I am unsure of why it is happening
                    }
                }

                if (Config.InterfaceMembersInCamelCase ||
                    typeDefinition.CustomAttributes.Any(a => a.AttributeType.Name == Config.InterfaceCamelCaseCustomAttribute))
                {
                    thingName = Helpers.ToCamelCaseFromPascalCase(thingName);
                }

                var collectionString = Helpers.GetCollectionPostfix(thing.CSharpType.CollectionLevel);

                thingName = TypeService.FixIfReservedWord(thingName);

                interfaceBlock
                .AddStatement($"{thingName}: {interfaceName}{collectionString};");

                if (Config.GenerateInterfaceClasses)
                {
                    classBlock
                    .AddStatement($"{thingName}: {typeName}{collectionString};");
                }
            }

            if (Config.GenerateInterfaceClasses)
            {
                if (hasBaseClass)
                {
                    classBlock
                    .AddAndUseBlock("constructor()")
                    .AddStatement("super();");
                }
            }
        }