Пример #1
0
        private static void WriteOutNestedTypes(Context.SyntaxAndSymbol first, OutputWriter writer)
        {
            //WriteOut All My nested classes
            Context.Push();

            var delegates = first.Syntax.DescendantNodes().OfType <DelegateDeclarationSyntax>()
                            .Select(o => new
            {
                Syntax   = o,
                Symbol   = TypeProcessor.GetDeclaredSymbol(o),
                TypeName = WriteType.TypeName((INamedTypeSymbol)TypeProcessor.GetDeclaredSymbol(o))
            }).Where(k => k.Symbol.ContainingType == Context.Instance.Type) // Ignore all nested delegates
                            .GroupBy(o => o.Symbol.ContainingNamespace.FullNameWithDot() + o.TypeName)
                            .ToList();


            delegates.ForEach(type => //.ForEach(type => //.Parallel(type =>
            {
                Context.Instance = new Context
                {
                    TypeName         = type.First().TypeName,
                    DelegatePartials =
                        type.Select(
                            o =>
                            new Context.DelegateSyntaxAndSymbol
                    {
                        Symbol = (INamedTypeSymbol)o.Symbol,
                        Syntax = o.Syntax
                    })
                        .Where(o => !Program.DoNotWrite.ContainsKey(o.Syntax))
                        .ToList()
                };

                if (Context.Instance.DelegatePartials.Count > 0)
                {
                    WriteDelegate.Go(writer);
                }
            });
            Context.Pop();

            Context.Push();
            var subclasses = first.Syntax.DescendantNodes().OfType <BaseTypeDeclarationSyntax>()
                             .Select(o => new
            {
                Syntax   = o,
                Symbol   = TypeProcessor.GetDeclaredSymbol(o),
                TypeName = WriteType.TypeName((INamedTypeSymbol)TypeProcessor.GetDeclaredSymbol(o))
            }).Where(k => k.Symbol.ContainingType == Context.Instance.Type) // Ignore all nested classes
                             .GroupBy(o => o.Symbol.ContainingNamespace.FullNameWithDot() + o.TypeName)
                             .ToList();

            subclasses.ForEach(type => //.ForEach(type => //.Parallel(type =>
            {
                Context.Instance = new Context
                {
                    TypeName = type.First().TypeName,
                    Partials =
                        type.Select(
                            o =>
                            new Context.SyntaxAndSymbol
                    {
                        Symbol = (INamedTypeSymbol)o.Symbol,
                        Syntax = o.Syntax
                    })
                        .Where(o => !Program.DoNotWrite.ContainsKey(o.Syntax))
                        .ToList()
                };

                if (Context.Instance.Partials.Count > 0)
                {
                    try
                    {
                        WriteType.Go(writer);
                    }
                    catch (Exception ex)
                    {
                        //TODO: remove this when done with CorLib
                        throw ex;
                    }
                }
            });

            Context.Pop();
        }
Пример #2
0
        private static IEnumerable <MemberDeclarationSyntax> WriteFields(List <MemberDeclarationSyntax> membersToWrite, Context.SyntaxAndSymbol first, OutputWriter writer)
        {
            var fields    = membersToWrite.OfType <FieldDeclarationSyntax>().ToList();
            var nonFields = membersToWrite.Except(fields); // also static fields should be separately dealt with

            //Not needed anymore ... reflection takes care of this
            //if (fields.Count > 0 && fields.Any(j => j.GetModifiers().Any(SyntaxKind.ConstKeyword) ||
            //                                        j.GetModifiers().Any(SyntaxKind.StaticKeyword)))
            //{
            //    writer.WriteLine("enum __staticFieldTuple = __Tuple!(" +
            //                     fields.Where(
            //                         j =>
            //                             j.GetModifiers().Any(SyntaxKind.ConstKeyword) ||
            //                             j.GetModifiers().Any(SyntaxKind.StaticKeyword))
            //                         .Select(
            //                             k =>
            //                                 "\"" +
            //                                 WriteIdentifierName.TransformIdentifier(
            //                                     k.Declaration.Variables[0].Identifier.ValueText) + "\"")
            //                         .Aggregate((i, j) => i + "," + j) + ");//Reflection Support");
            //}

            var structLayout = first.Syntax.GetAttribute(Context.StructLayout);

            if (structLayout != null)
            {
                LayoutKind value = LayoutKind.Auto;
                if (
                    structLayout.ArgumentList.Arguments.Any(
                        k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Value"))
                {
                    value =
                        (LayoutKind)
                        Enum.Parse(typeof(LayoutKind),
                                   structLayout.ArgumentList.Arguments.FirstOrDefault(
                                       k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Value")
                                   .Expression.ToFullString()
                                   .SubstringAfterLast('.'));
                }

                else if (structLayout.ArgumentList.Arguments.Count > 0 &&
                         structLayout.ArgumentList.Arguments[0].NameEquals == null)
                {
                    value =
                        (LayoutKind)
                        Enum.Parse(typeof(LayoutKind),
                                   structLayout.ArgumentList.Arguments[0].Expression.ToFullString()
                                   .SubstringAfterLast('.'));
                }
                int     pack    = -1;
                int     size    = -1;
                CharSet charset = CharSet.Auto;
                //					if (structLayout.ArgumentList.Arguments.Count > 1)
                {
                    try
                    {
                        if (
                            structLayout.ArgumentList.Arguments.Any(
                                k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "CharSet"))
                        {
                            charset =
                                (CharSet)
                                Enum.Parse(typeof(CharSet),
                                           structLayout.ArgumentList.Arguments.FirstOrDefault(
                                               k =>
                                               k.NameEquals != null &&
                                               k.NameEquals.Name.ToFullString().Trim() == "CharSet")
                                           .Expression.ToFullString()
                                           .SubstringAfterLast('.'));
                            //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                        }
                        //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                        else if (structLayout.ArgumentList.Arguments.Count > 1 &&
                                 structLayout.ArgumentList.Arguments[1].NameEquals == null)
                        {
                            charset =
                                (CharSet)
                                Enum.Parse(typeof(CharSet),
                                           structLayout.ArgumentList.Arguments[1].Expression.ToFullString()
                                           .SubstringAfterLast('.'));
                        }
                    }
                    catch (Exception ex)
                    {
                    }

                    try
                    {
                        if (
                            structLayout.ArgumentList.Arguments.Any(
                                k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Pack"))
                        {
                            pack =
                                int.Parse(
                                    structLayout.ArgumentList.Arguments.FirstOrDefault(
                                        k =>
                                        k.NameEquals != null &&
                                        k.NameEquals.Name.ToFullString().Trim() == "Pack")
                                    .Expression.ToFullString());
                        }
                        //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                        else if (structLayout.ArgumentList.Arguments.Count > 2 &&
                                 structLayout.ArgumentList.Arguments[2].NameEquals == null)
                        {
                            pack = int.Parse(structLayout.ArgumentList.Arguments[2].Expression.ToFullString());
                        }
                    }
                    catch (Exception ex)
                    {
                    }

                    try
                    {
                        if (
                            structLayout.ArgumentList.Arguments.Any(
                                k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Size"))
                        {
                            size =
                                int.Parse(
                                    structLayout.ArgumentList.Arguments.FirstOrDefault(
                                        k => k.NameColon != null && k.NameColon.ToFullString().Trim() == "Size")
                                    .Expression.ToFullString());
                        }
                        //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                        else if (structLayout.ArgumentList.Arguments.Count > 3 &&
                                 structLayout.ArgumentList.Arguments[3].NameEquals == null)
                        {
                            size = int.Parse(structLayout.ArgumentList.Arguments[3].Expression.ToFullString());
                        }
                    }
                    catch (Exception ex)
                    {
                    }

                    //						size = int.Parse (structLayout.ArgumentList.Arguments [3].Expression.ToFullString ());
                }
                //					var pack = structLayout.ArgumentList.Arguments.FirstOrDefault (k => k.NameColon.Name.ToFullString() == "Pack");
                //					var charset = structLayout.ArgumentList.Arguments.FirstOrDefault (k => k.NameColon.Name.ToFullString() == "CharSet");
                //					var size = structLayout.ArgumentList.Arguments.FirstOrDefault (k => k.NameColon.Name.ToFullString() == "Size");

                if (value == LayoutKind.Explicit)
                {
                    var fieldGroups =
                        fields.GroupBy(f => f.GetAttribute(Context.FieldOffset).ArgumentList.Arguments[0].ToString())
                        .OrderBy(k => k.Key);
                    writer.Indent++;

                    foreach (var group in fieldGroups)
                    {
                        writer.WriteLine("//FieldOffset(" + @group.Key + ")");
                        writer.WriteLine("union {");
                        foreach (var member in @group)
                        {
                            Core.Write(writer, member);
                        }
                        writer.WriteLine("}");
                    }

                    //						foreach (var member in fields)
                    //						{
                    //							//                    writer.WriteLine();
                    //							Core.Write (writer, member);
                    //						}
                }
                else if (value == LayoutKind.Sequential)
                {
                    fields = SortFields(fields);

                    writer.Indent++;

                    foreach (var member in fields)
                    {
                        if (pack != -1)
                        {
                            writer.WriteLine("align (" + pack + "): //Pack = " + pack);
                        }
                        //                    writer.WriteLine();
                        Core.Write(writer, member);
                    }
                }

                else
                {
                    //Looks like C# aligns to 1 by default ... don't know about D...
                    fields = SortFields(fields);

                    writer.Indent++;
                    foreach (var member in fields)
                    {
                        pack = 1;
                        //TODO: on mac osx and mono this is required, on windows, it causes and issue
                        //                            writer.WriteLine("align (" + pack + "): //Pack = " + pack + " C# default");
                        //                    writer.WriteLine();
                        Core.Write(writer, member);
                    }
                }
            }
            else
            {
                //Looks like C# aligns to 1 by default ... don't know about D...
                fields = SortFields(fields);

                writer.Indent++;
                foreach (var member in fields)
                {
                    var pack = 1;
                    //TODO: on mac osx and mono this is required, on windows, it causes an issue (sizes are different)
                    //                        writer.WriteLine("align (" + pack + "): //Pack = " + pack + "C# default");
                    //                    writer.WriteLine();
                    Core.Write(writer, member);
                }
            }

            return(nonFields);
        }