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(); }
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); }