Example #1
0
        private static MethodDeclarationSyntax GenerateMethodDeclaration()
        {
            return(MethodDeclaration(
                       Modifiers.Protected_Virtual(),
                       PredefinedBoolType(),
                       Identifier("ShouldVisit"),
                       ParameterList(Parameter(IdentifierName("IPropertySymbol"), "propertySymbol")),
                       Block(
                           SwitchStatement(
                               SimpleMemberAccessExpression(
                                   SimpleMemberAccessExpression(
                                       IdentifierName("propertySymbol"),
                                       IdentifierName("ContainingType")),
                                   IdentifierName("Name")),
                               GenerateSections().ToSyntaxList().Add(DefaultSwitchSection(Block(ThrowNewInvalidOperationException(ParseExpression(@"$""Unrecognized type '{propertySymbol.ContainingType.Name}'""")))))))));

            IEnumerable <SwitchSectionSyntax> GenerateSections()
            {
                foreach (INamedTypeSymbol typeSymbol in Symbols.SyntaxSymbols)
                {
                    if (typeSymbol.IsAbstract)
                    {
                        continue;
                    }

                    SyntaxList <SwitchSectionSyntax> sections = default;

                    foreach (IGrouping <bool, IPropertySymbol> grouping in Symbols.GetPropertySymbols(typeSymbol, skipObsolete: false)
                             .GroupBy(f => f.HasAttribute(MetadataNames.System_ObsoleteAttribute) ||
                                      (typeSymbol.Name == "AnonymousMethodExpressionSyntax" && f.Name == "Block"))
                             .OrderBy(f => f.Key))
                    {
                        if (!grouping.Key)
                        {
                            sections = sections.Add(SwitchSection(GenerateLabels(grouping).ToSyntaxList(), ReturnStatement(TrueLiteralExpression())));
                        }
                        else
                        {
                            sections = sections.Add(SwitchSection(GenerateLabels(grouping).ToSyntaxList(), ReturnStatement(FalseLiteralExpression())));
                        }
                    }

                    Debug.Assert(sections.Any());

                    sections = sections.Add(DefaultSwitchSection(ThrowNewInvalidOperationException(ParseExpression(@"$""Unrecognized property '{propertySymbol.Name}'"""))));

                    yield return(SwitchSection(
                                     CaseSwitchLabel(StringLiteralExpression(typeSymbol.Name)),
                                     Block(
                                         SwitchStatement(
                                             SimpleMemberAccessExpression(IdentifierName("propertySymbol"), IdentifierName("Name")),
                                             sections))));
                }

                IEnumerable <SwitchLabelSyntax> GenerateLabels(IEnumerable <IPropertySymbol> propertySymbols)
                {
                    foreach (IPropertySymbol propertySymbol in propertySymbols)
                    {
                        yield return(CaseSwitchLabel(StringLiteralExpression(propertySymbol.Name)));
                    }
                }
            }
        }