Exemple #1
0
        static MemberDeclarationSyntax MakeConstructor(ClassDeclarationSyntax @class, TypeSyntax returnType, MethodDeclarationSyntax method)
        {
            var assignments = method.ParameterList
                              .Parameters
                              .Select(p =>
                                      ExpressionStatement(
                                          AssignmentExpression(
                                              SyntaxKind.SimpleAssignmentExpression,
                                              IdentifierName(CodeGenUtil.MakeFirstCharUpper(p.Identifier.Text)),
                                              IdentifierName(p.Identifier.Text))));

            return(ConstructorDeclaration(Identifier(method.Identifier.Text))
                   .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
                   .WithParameterList(method.ParameterList)
                   .WithBody(Block(List(assignments))));
        }
Exemple #2
0
        static MemberDeclarationSyntax MakeField(TypeSyntax returnType, ParameterSyntax p)
        {
            var fieldName = CodeGenUtil.MakeFirstCharUpper(p.Identifier.Text);

            var field = FieldDeclaration(
                VariableDeclaration(p.Type)
                .WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier(fieldName)))))
                        .WithModifiers(
                TokenList(
                    new[] {
                Token(SyntaxKind.PublicKeyword),
                Token(SyntaxKind.ReadOnlyKeyword)
            }))
                        .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));;

            return(field);
        }
Exemple #3
0
        static MethodDeclarationSyntax MakeMapFunction(
            SyntaxToken applyToIdentifier,
            SyntaxList <TypeParameterConstraintClauseSyntax> applyToConstraints,
            MethodDeclarationSyntax[] applyToMembers,
            TypeParameterListSyntax applyToTypeParams,
            MethodDeclarationSyntax pure)
        {
            var genA = applyToTypeParams.Parameters.First().ToString();
            var genB = CodeGenUtil.NextGenName(genA);
            var genC = CodeGenUtil.NextGenName(genB);

            var typeA       = MakeTypeName(applyToIdentifier.Text, genA);
            var typeB       = MakeTypeName(applyToIdentifier.Text, genB);
            var typeC       = MakeTypeName(applyToIdentifier.Text, genC);
            var mapFuncType = ParseTypeName($"System.Func<{genA}, {genB}>");
            var pureTypeA   = MakeTypeName(pure.Identifier.Text, genA);
            var pureTypeB   = MakeTypeName(pure.Identifier.Text, genB);

            var mapFunc = InvocationExpression(
                MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    InvocationExpression(
                        MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            IdentifierName("v"),
                            IdentifierName("Next")))
                    .WithArgumentList(ArgumentList(SingletonSeparatedList <ArgumentSyntax>(Argument(IdentifierName("n"))))),
                    IdentifierName("Map")))
                          .WithArgumentList(
                ArgumentList(
                    SingletonSeparatedList <ArgumentSyntax>(
                        Argument(
                            IdentifierName("f")))));

            var pureFunc =
                new SyntaxNodeOrToken[]
            {
                SwitchExpressionArm(
                    DeclarationPattern(
                        pureTypeA,
                        SingleVariableDesignation(Identifier("v"))),
                    ObjectCreationExpression(pureTypeB)
                    .WithArgumentList(
                        ArgumentList(
                            SingletonSeparatedList <ArgumentSyntax>(
                                Argument(
                                    InvocationExpression(IdentifierName("f"))
                                    .WithArgumentList(
                                        ArgumentList(
                                            SingletonSeparatedList <ArgumentSyntax>(
                                                Argument(
                                                    MemberAccessExpression(
                                                        SyntaxKind.SimpleMemberAccessExpression,
                                                        IdentifierName("v"),
                                                        IdentifierName(CodeGenUtil.MakeFirstCharUpper(pure.ParameterList.Parameters.First().Identifier.Text)))))))))))),
                Token(SyntaxKind.CommaToken)
            };

            var termimalFuncs = applyToMembers
                                .Where(m => m != pure && m.AttributeLists != null && m.AttributeLists.SelectMany(a => a.Attributes).Any(a => a.Name.ToString() == "Pure"))
                                .SelectMany(m =>
                                            new SyntaxNodeOrToken[]
            {
                SwitchExpressionArm(
                    DeclarationPattern(
                        ParseTypeName($"{m.Identifier.Text}<{genA}>"),
                        SingleVariableDesignation(Identifier("v"))),
                    ObjectCreationExpression(MakeTypeName(m.Identifier.Text, genB))
                    .WithArgumentList(
                        ArgumentList(
                            SeparatedList <ArgumentSyntax>(
                                m.ParameterList
                                .Parameters
                                .Select(p =>
                                        Argument(
                                            MemberAccessExpression(
                                                SyntaxKind.SimpleMemberAccessExpression,
                                                IdentifierName("v"),
                                                IdentifierName(CodeGenUtil.MakeFirstCharUpper(p.Identifier))))))))),
                Token(SyntaxKind.CommaToken)
            });


            var freeFuncs = applyToMembers
                            .Where(m => m.AttributeLists == null || !m.AttributeLists.SelectMany(a => a.Attributes).Any(a => a.Name.ToString() == "Pure"))
                            .SelectMany(m =>
                                        new SyntaxNodeOrToken[]
            {
                SwitchExpressionArm(
                    DeclarationPattern(
                        ParseTypeName($"{m.Identifier.Text}<{genA}>"),
                        SingleVariableDesignation(Identifier("v"))),
                    ObjectCreationExpression(MakeTypeName(m.Identifier.Text, genB))
                    .WithArgumentList(
                        ArgumentList(
                            SeparatedList <ArgumentSyntax>(
                                Enumerable.Concat(
                                    m.ParameterList
                                    .Parameters
                                    .Take(m.ParameterList.Parameters.Count - 1)
                                    .SelectMany(p =>
                                                new SyntaxNodeOrToken[] {
                    Argument(
                        MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            IdentifierName("v"),
                            IdentifierName(CodeGenUtil.MakeFirstCharUpper(p.Identifier.Text)))),
                    Token(SyntaxKind.CommaToken)
                }),
                                    new SyntaxNodeOrToken [1] {
                    Argument(SimpleLambdaExpression(Parameter(Identifier("n")), mapFunc))
                }))))),
                Token(SyntaxKind.CommaToken)
            });

            var tokens = new List <SyntaxNodeOrToken>();

            tokens.AddRange(pureFunc);
            tokens.AddRange(termimalFuncs);
            tokens.AddRange(freeFuncs);
            tokens.Add(
                SwitchExpressionArm(
                    DiscardPattern(),
                    ThrowExpression(
                        ObjectCreationExpression(
                            QualifiedName(
                                IdentifierName("System"),
                                IdentifierName("NotSupportedException")))
                        .WithArgumentList(ArgumentList()))));

            return(MethodDeclaration(typeB, Identifier("Map"))
                   .WithModifiers(
                       TokenList(new[] { Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword) }))
                   .WithTypeParameterList(
                       TypeParameterList(
                           SeparatedList <TypeParameterSyntax>(
                               new SyntaxNodeOrToken[]
            {
                TypeParameter(
                    Identifier(genA)),
                Token(SyntaxKind.CommaToken), TypeParameter(
                    Identifier(genB))
            })))
                   .WithParameterList(
                       ParameterList(
                           SeparatedList <ParameterSyntax>(
                               new SyntaxNodeOrToken[]
            {
                Parameter(
                    Identifier("ma"))
                .WithModifiers(
                    TokenList(
                        Token(SyntaxKind.ThisKeyword)))
                .WithType(typeA),
                Token(SyntaxKind.CommaToken), Parameter(
                    Identifier("f"))
                .WithType(mapFuncType)
            })))
                   .WithExpressionBody(
                       ArrowExpressionClause(
                           SwitchExpression(
                               IdentifierName("ma"))
                           .WithArms(SeparatedList <SwitchExpressionArmSyntax>(tokens))))
                   .WithSemicolonToken(
                       Token(SyntaxKind.SemicolonToken))
                   .NormalizeWhitespace());
        }