Пример #1
0
        private async Task <CSharpSyntaxNode> GetInitializerFromNameAndTypeAsync(ITypeSymbol typeSymbol,
                                                                                 VBSyntax.ModifiedIdentifierSyntax name, CSharpSyntaxNode initializer)
        {
            if (!SyntaxTokenExtensions.IsKind(name.Nullable, SyntaxKind.None))
            {
                if (typeSymbol.IsArrayType())
                {
                    initializer = null;
                }
            }

            var rankSpecifiers = await ConvertArrayRankSpecifierSyntaxesAsync(name.ArrayRankSpecifiers, name.ArrayBounds, false);

            if (rankSpecifiers.Count > 0)
            {
                var rankSpecifiersWithSizes = await ConvertArrayRankSpecifierSyntaxesAsync(name.ArrayRankSpecifiers, name.ArrayBounds);

                var arrayTypeSyntax = ((ArrayTypeSyntax)GetTypeSyntax(typeSymbol)).WithRankSpecifiers(rankSpecifiersWithSizes);
                if (rankSpecifiersWithSizes.SelectMany(ars => ars.Sizes).Any(e => !e.IsKind(CSSyntaxKind.OmittedArraySizeExpression)))
                {
                    initializer = SyntaxFactory.ArrayCreationExpression(arrayTypeSyntax);
                }
                else if (initializer is ImplicitArrayCreationExpressionSyntax iaces && iaces.Initializer != null)
                {
                    initializer = SyntaxFactory.ArrayCreationExpression(arrayTypeSyntax, iaces.Initializer);
                }
            }

            return(initializer);
        }
Пример #2
0
        private async Task <CSharpSyntaxNode> GetInitializerFromNameAndType(ITypeSymbol typeSymbol,
                                                                            ModifiedIdentifierSyntax name, CSharpSyntaxNode initializer)
        {
            if (!SyntaxTokenExtensions.IsKind(name.Nullable, SyntaxKind.None))
            {
                if (typeSymbol.IsArrayType())
                {
                    initializer = null;
                }
            }

            var rankSpecifiers = await ConvertArrayRankSpecifierSyntaxes(name.ArrayRankSpecifiers, name.ArrayBounds, false);

            if (rankSpecifiers.Count > 0)
            {
                var rankSpecifiersWithSizes = await ConvertArrayRankSpecifierSyntaxes(name.ArrayRankSpecifiers, name.ArrayBounds);

                if (!rankSpecifiersWithSizes.SelectMany(ars => ars.Sizes).OfType <OmittedArraySizeExpressionSyntax>().Any())
                {
                    var arrayTypeSyntax = (ArrayTypeSyntax)GetTypeSyntax(typeSymbol);
                    arrayTypeSyntax = arrayTypeSyntax.WithRankSpecifiers(rankSpecifiersWithSizes);
                    initializer     = SyntaxFactory.ArrayCreationExpression(arrayTypeSyntax);
                }
            }

            return(initializer);
        }
Пример #3
0
        static Dictionary <string, VariableDeclarationSyntax> SplitVariableDeclarations(VBSyntax.VariableDeclaratorSyntax declarator, VBasic.VisualBasicSyntaxVisitor <CSharpSyntaxNode> nodesVisitor, SemanticModel semanticModel)
        {
            var rawType = (TypeSyntax)declarator.AsClause?.TypeSwitch(
                (VBSyntax.SimpleAsClauseSyntax c) => c.Type,
                (VBSyntax.AsNewClauseSyntax c) => VBasic.SyntaxExtensions.Type(c.NewExpression),
                _ => { throw new NotImplementedException($"{_.GetType().FullName} not implemented!"); }
                )?.Accept(nodesVisitor) ?? SyntaxFactory.ParseTypeName("var");

            var initializer = (ExpressionSyntax)declarator.AsClause?.TypeSwitch(
                (VBSyntax.SimpleAsClauseSyntax _) => declarator.Initializer?.Value,
                (VBSyntax.AsNewClauseSyntax c) => c.NewExpression
                )?.Accept(nodesVisitor) ?? (ExpressionSyntax)declarator.Initializer?.Value.Accept(nodesVisitor);

            var newDecls = new Dictionary <string, VariableDeclarationSyntax>();

            foreach (var name in declarator.Names)
            {
                var type = rawType;
                if (!SyntaxTokenExtensions.IsKind(name.Nullable, VBasic.SyntaxKind.None))
                {
                    if (type is ArrayTypeSyntax)
                    {
                        type = ((ArrayTypeSyntax)type).WithElementType(
                            SyntaxFactory.NullableType(((ArrayTypeSyntax)type).ElementType));
                        initializer = null;
                    }
                    else
                    {
                        type = SyntaxFactory.NullableType(type);
                    }
                }

                var rankSpecifiers = NodesVisitor.ConvertArrayRankSpecifierSyntaxes(name.ArrayRankSpecifiers, name.ArrayBounds, nodesVisitor, semanticModel, false);
                if (rankSpecifiers.Count > 0)
                {
                    var rankSpecifiersWithSizes = NodesVisitor.ConvertArrayRankSpecifierSyntaxes(name.ArrayRankSpecifiers, name.ArrayBounds, nodesVisitor, semanticModel);
                    if (!rankSpecifiersWithSizes.SelectMany(ars => ars.Sizes).OfType <OmittedArraySizeExpressionSyntax>().Any())
                    {
                        initializer =
                            SyntaxFactory.ArrayCreationExpression(
                                SyntaxFactory.ArrayType(type, rankSpecifiersWithSizes));
                    }
                    type = SyntaxFactory.ArrayType(type, rankSpecifiers);
                }

                VariableDeclarationSyntax decl;
                var    v = SyntaxFactory.VariableDeclarator(ConvertIdentifier(name.Identifier, semanticModel), null, initializer == null ? null : SyntaxFactory.EqualsValueClause(initializer));
                string k = type.ToString();
                if (newDecls.TryGetValue(k, out decl))
                {
                    newDecls[k] = decl.AddVariables(v);
                }
                else
                {
                    newDecls[k] = SyntaxFactory.VariableDeclaration(type, SyntaxFactory.SingletonSeparatedList(v));
                }
            }

            return(newDecls);
        }
Пример #4
0
        public static ArrowExpressionClauseSyntax GenerateSpanNameValues(MemberDeclarationMeta memberdecl) //=> { byte, byte, byte, byte}
        {
            SeparatedSyntaxList <ExpressionSyntax> ArrayInitExpr(MemberDeclarationMeta memberdecl)
            {
                SeparatedSyntaxList <ExpressionSyntax> expr = new SeparatedSyntaxList <ExpressionSyntax>();

                foreach (var byteItem in Encoding.UTF8.GetBytes(memberdecl.StringFieldNameAlias))
                {
                    expr = expr.Add(Basics.NumberLiteral(byteItem));
                }
                return(expr);
            }

            ArrayRankSpecifierSyntax ArrayRank(MemberDeclarationMeta memberdecl)
            {
                return(SF.ArrayRankSpecifier().AddSizes(Basics.NumberLiteral(memberdecl.StringFieldNameAlias.Length)));
            }

            return(SF.ArrowExpressionClause(
                       SF.ArrayCreationExpression(
                           SF.ArrayType(
                               SF.PredefinedType(SF.Token(SyntaxKind.ByteKeyword)),
                               SF.SingletonList <ArrayRankSpecifierSyntax>(ArrayRank(memberdecl))),


                           SF.InitializerExpression(SyntaxKind.ArrayInitializerExpression, ArrayInitExpr(memberdecl))
                           )
                       ));
        }
        private static ExpressionSyntax EmptyCharArrayExpression()
        {
            var literalExpressionSyntax =
                SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(0));
            var arrayRankSpecifierSyntax = ArrayRankSpecifier(literalExpressionSyntax);
            var arrayTypeSyntax          = CharArrayType().WithRankSpecifiers(arrayRankSpecifierSyntax);

            return(SyntaxFactory.ArrayCreationExpression(arrayTypeSyntax));
        }
            private ExpressionStatementSyntax CreateNewArrayAssignment(VBSyntax.ExpressionSyntax vbArrayExpression,
                                                                       ExpressionSyntax csArrayExpression, List <ExpressionSyntax> convertedBounds,
                                                                       int nodeSpanStart)
            {
                var arrayRankSpecifierSyntax = SyntaxFactory.ArrayRankSpecifier(SyntaxFactory.SeparatedList(convertedBounds));
                var convertedType            = (IArrayTypeSymbol)_semanticModel.GetTypeInfo(vbArrayExpression).ConvertedType;
                var typeSyntax    = GetTypeSyntaxFromTypeSymbol(convertedType.ElementType, nodeSpanStart);
                var arrayCreation =
                    SyntaxFactory.ArrayCreationExpression(SyntaxFactory.ArrayType(typeSyntax,
                                                                                  SyntaxFactory.SingletonList(arrayRankSpecifierSyntax)));
                var assignmentExpressionSyntax =
                    SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, csArrayExpression, arrayCreation);
                var newArrayAssignment = SyntaxFactory.ExpressionStatement(assignmentExpressionSyntax);

                return(newArrayAssignment);
            }
        /// <summary>
        /// Returns syntax for individual switch cases within the <see cref="IEventInvoker{T}.GetArgumentTypes"/> method.
        /// </summary>
        /// <param name="methodDescription">
        /// The method description.
        /// </param>
        /// <returns>
        /// Syntax for individual switch cases within the <see cref="IEventInvoker{T}.GetArgumentTypes"/> method.
        /// </returns>
        private static StatementSyntax GenerateGetTypeArgumentsSwitchBlock(ActorMethodDescription methodDescription)
        {
            var method     = methodDescription.MethodInfo;
            var parameters = method.GetParameters().ToList();

            var argumentTypes =
                parameters.Select(p => SF.TypeOfExpression(p.ParameterType.GetTypeSyntax()))
                .Cast <ExpressionSyntax>()
                .ToArray();

            var argumentTypeArray = SF.ArrayCreationExpression(typeof(Type).GetArrayTypeSyntax())
                                    .WithInitializer(
                SF.InitializerExpression(SyntaxKind.ArrayInitializerExpression).AddExpressions(argumentTypes));

            return(SF.ReturnStatement(argumentTypeArray));
        }
Пример #8
0
        ArgumentListSyntax GetArgumentListSyntax()
        {
            var arguments = GetArgumentExpressions().Select(e => SF.Argument(e));

            return(SF.ArgumentList(SF.SeparatedList(arguments)));

            IEnumerable <ExpressionSyntax> GetArgumentExpressions()
            {
                if (Method.IsStatic)
                {
                    yield return(SF.TypeOfExpression(Symbols.GetNameSyntax(Type)));
                }

                yield return(CreateArgumentsArray());
            }

            ArrayCreationExpressionSyntax CreateArgumentsArray()
            {
                return(SF.ArrayCreationExpression(
                           SF.Token(SyntaxKind.NewKeyword),
                           SF.ArrayType(SF.ParseTypeName("object[]")),
                           SF.InitializerExpression(
                               SyntaxKind.ArrayInitializerExpression,
                               SF.Token(SyntaxKind.OpenBraceToken),
                               SF.SeparatedList(GetArguments()),
                               SF.Token(SyntaxKind.CloseBraceToken)
                               )
                           ));

                IEnumerable <ExpressionSyntax> GetArguments()
                {
                    if (Method.Parameters == null)
                    {
                        yield break;
                    }

                    foreach (Parameter parameter in Method.Parameters)
                    {
                        yield return(Symbols.GetNameSyntax(parameter));
                    }
                }
            }
        }
        private (TypeSyntax, ExpressionSyntax) AdjustFromName(TypeSyntax rawType,
                                                              ModifiedIdentifierSyntax name, ExpressionSyntax initializer)
        {
            var type = rawType;

            if (!SyntaxTokenExtensions.IsKind(name.Nullable, SyntaxKind.None))
            {
                if (type is ArrayTypeSyntax)
                {
                    type = ((ArrayTypeSyntax)type).WithElementType(
                        SyntaxFactory.NullableType(((ArrayTypeSyntax)type).ElementType));
                    initializer = null;
                }
                else
                {
                    type = SyntaxFactory.NullableType(type);
                }
            }

            var rankSpecifiers = ConvertArrayRankSpecifierSyntaxes(name.ArrayRankSpecifiers, name.ArrayBounds, false);

            if (rankSpecifiers.Count > 0)
            {
                var rankSpecifiersWithSizes = ConvertArrayRankSpecifierSyntaxes(name.ArrayRankSpecifiers,
                                                                                name.ArrayBounds);
                if (!rankSpecifiersWithSizes.SelectMany(ars => ars.Sizes).OfType <OmittedArraySizeExpressionSyntax>().Any())
                {
                    initializer =
                        SyntaxFactory.ArrayCreationExpression(
                            SyntaxFactory.ArrayType(type, rankSpecifiersWithSizes));
                }

                type = SyntaxFactory.ArrayType(type, rankSpecifiers);
            }

            return(type, initializer);
        }
Пример #10
0
        /// <summary>
        /// Generates invoker methods.
        /// </summary>
        /// <param name="grainType">The grain type.</param>
        /// <param name="onEncounteredType">
        /// The callback which is invoked when a type is encountered.
        /// </param>
        /// <returns>Invoker methods for the provided grain type.</returns>
        private static MemberDeclarationSyntax[] GenerateInvokeMethods(Type grainType, Action <Type> onEncounteredType)
        {
            var baseReference = SF.BaseExpression();
            var methods       = GrainInterfaceUtils.GetMethods(grainType);
            var members       = new List <MemberDeclarationSyntax>();

            foreach (var method in methods)
            {
                onEncounteredType(method.ReturnType);
                var methodId         = GrainInterfaceUtils.ComputeMethodId(method);
                var methodIdArgument =
                    SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(methodId)));

                // Construct a new object array from all method arguments.
                var parameters = method.GetParameters();
                var body       = new List <StatementSyntax>();
                foreach (var parameter in parameters)
                {
                    onEncounteredType(parameter.ParameterType);
                    if (typeof(IGrainObserver).GetTypeInfo().IsAssignableFrom(parameter.ParameterType))
                    {
                        body.Add(
                            SF.ExpressionStatement(
                                CheckGrainObserverParamInternalExpression.Invoke()
                                .AddArgumentListArguments(SF.Argument(parameter.Name.ToIdentifierName()))));
                    }
                }

                // Get the parameters argument value.
                ExpressionSyntax args;
                if (parameters.Length == 0)
                {
                    args = SF.LiteralExpression(SyntaxKind.NullLiteralExpression);
                }
                else
                {
                    args =
                        SF.ArrayCreationExpression(typeof(object).GetArrayTypeSyntax())
                        .WithInitializer(
                            SF.InitializerExpression(SyntaxKind.ArrayInitializerExpression)
                            .AddExpressions(parameters.Select(GetParameterForInvocation).ToArray()));
                }

                var options = GetInvokeOptions(method);

                // Construct the invocation call.
                if (method.ReturnType == typeof(void))
                {
                    var invocation = SF.InvocationExpression(baseReference.Member("InvokeOneWayMethod"))
                                     .AddArgumentListArguments(methodIdArgument)
                                     .AddArgumentListArguments(SF.Argument(args));

                    if (options != null)
                    {
                        invocation = invocation.AddArgumentListArguments(options);
                    }

                    body.Add(SF.ExpressionStatement(invocation));
                }
                else
                {
                    var returnType = method.ReturnType == typeof(Task)
                                         ? typeof(object)
                                         : method.ReturnType.GenericTypeArguments[0];
                    var invocation =
                        SF.InvocationExpression(baseReference.Member("InvokeMethodAsync", returnType))
                        .AddArgumentListArguments(methodIdArgument)
                        .AddArgumentListArguments(SF.Argument(args));

                    if (options != null)
                    {
                        invocation = invocation.AddArgumentListArguments(options);
                    }

                    body.Add(SF.ReturnStatement(invocation));
                }

                members.Add(method.GetDeclarationSyntax().AddBodyStatements(body.ToArray()));
            }

            return(members.ToArray());
        }
Пример #11
0
        /// <summary>
        /// Generates invoker methods.
        /// </summary>
        /// <param name="grainType">The grain type.</param>
        /// <param name="onEncounteredType">
        /// The callback which is invoked when a type is encountered.
        /// </param>
        /// <returns>Invoker methods for the provided grain type.</returns>
        private static MemberDeclarationSyntax[] GenerateInvokeMethods(Type grainType, Action <Type> onEncounteredType)
        {
            var baseReference = SF.BaseExpression();
            var methods       = GrainInterfaceUtils.GetMethods(grainType);
            var members       = new List <MemberDeclarationSyntax>();

            foreach (var method in methods)
            {
                onEncounteredType(method.ReturnType);
                var methodId         = GrainInterfaceUtils.ComputeMethodId(method);
                var methodIdArgument =
                    SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(methodId)));

                // Construct a new object array from all method arguments.
                var parameters = method.GetParameters();
                var body       = new List <StatementSyntax>();
                foreach (var parameter in parameters)
                {
                    onEncounteredType(parameter.ParameterType);
                    if (typeof(IGrainObserver).IsAssignableFrom(parameter.ParameterType))
                    {
                        body.Add(
                            SF.ExpressionStatement(
                                CheckGrainObserverParamInternalExpression.Invoke()
                                .AddArgumentListArguments(SF.Argument(parameter.Name.ToIdentifierName()))));
                    }
                }

                // Get the parameters argument value.
                ExpressionSyntax args;
                if (method.IsGenericMethodDefinition)
                {
                    // Create an arguments array which includes the method's type parameters followed by the method's parameter list.
                    var allParameters = new List <ExpressionSyntax>();
                    foreach (var typeParameter in method.GetGenericArguments())
                    {
                        allParameters.Add(SF.TypeOfExpression(typeParameter.GetTypeSyntax()));
                    }

                    allParameters.AddRange(parameters.Select(GetParameterForInvocation));

                    args =
                        SF.ArrayCreationExpression(typeof(object).GetArrayTypeSyntax())
                        .WithInitializer(
                            SF.InitializerExpression(SyntaxKind.ArrayInitializerExpression)
                            .AddExpressions(allParameters.ToArray()));
                }
                else if (parameters.Length == 0)
                {
                    args = SF.LiteralExpression(SyntaxKind.NullLiteralExpression);
                }
                else
                {
                    args =
                        SF.ArrayCreationExpression(typeof(object).GetArrayTypeSyntax())
                        .WithInitializer(
                            SF.InitializerExpression(SyntaxKind.ArrayInitializerExpression)
                            .AddExpressions(parameters.Select(GetParameterForInvocation).ToArray()));
                }

                var options = GetInvokeOptions(method);

                // Construct the invocation call.
                var isOneWayTask = method.GetCustomAttribute <OneWayAttribute>() != null;
                if (method.ReturnType == typeof(void) || isOneWayTask)
                {
                    var invocation = SF.InvocationExpression(baseReference.Member("InvokeOneWayMethod"))
                                     .AddArgumentListArguments(methodIdArgument)
                                     .AddArgumentListArguments(SF.Argument(args));

                    if (options != null)
                    {
                        invocation = invocation.AddArgumentListArguments(options);
                    }

                    body.Add(SF.ExpressionStatement(invocation));

                    if (isOneWayTask)
                    {
                        if (method.ReturnType != typeof(Task))
                        {
                            throw new CodeGenerationException(
                                      $"Method {grainType.GetParseableName()}.{method.Name} is marked with [{nameof(OneWayAttribute)}], " +
                                      $"but has a return type which is not assignable from {typeof(Task)}");
                        }

                        var done = typeof(Task).GetNameSyntax(true).Member((object _) => Task.CompletedTask);
                        body.Add(SF.ReturnStatement(done));
                    }
                }
                else
                {
                    var returnType = method.ReturnType == typeof(Task)
                                         ? typeof(object)
                                         : method.ReturnType.GenericTypeArguments[0];
                    var invocation =
                        SF.InvocationExpression(baseReference.Member("InvokeMethodAsync", returnType))
                        .AddArgumentListArguments(methodIdArgument)
                        .AddArgumentListArguments(SF.Argument(args));

                    if (options != null)
                    {
                        invocation = invocation.AddArgumentListArguments(options);
                    }

                    ExpressionSyntax returnContent = invocation;
                    if (method.ReturnType.IsGenericType &&
                        method.ReturnType.GetGenericTypeDefinition().FullName == "System.Threading.Tasks.ValueTask`1")
                    {
                        // Wrapping invocation expression with initialization of ValueTask (e.g. new ValueTask<int>(base.InvokeMethod()))
                        returnContent =
                            SF.ObjectCreationExpression(method.ReturnType.GetTypeSyntax())
                            .AddArgumentListArguments(SF.Argument(SF.ExpressionStatement(invocation).Expression));
                    }

                    body.Add(SF.ReturnStatement(returnContent));
                }

                members.Add(method.GetDeclarationSyntax().AddBodyStatements(body.ToArray()));
            }

            return(members.ToArray());
        }
Пример #12
0
        /// <summary>
        ///     Create a class that implements <see cref="ICommand"/>.
        ///
        ///     The implementation will execute the given <see cref="method"/>.
        /// </summary>
        /// <param name="id">The unique identifier of the command for <see cref="ICommand.Id"/>.</param>
        /// <param name="className">The new class name.</param>
        /// <param name="moduleType">The type that contains the <see cref="method"/>.</param>
        /// <param name="method">The method that should be executed when <see cref="ICommand.ExecuteAsync"/> is called.</param>
        /// <returns>The <see cref="ClassDeclarationSyntax"/>.</returns>
        private ClassDeclarationSyntax CreateCommandClass(
            string id,
            IReadOnlyList <string> aliases,
            string className,
            Type moduleType,
            MethodInfo method)
        {
            var permission      = ModuleUtils.GetPermissionName(moduleType, method);
            var moduleName      = ModuleUtils.GetModuleName(moduleType);
            var attr            = method.GetCustomAttribute <CommandAttribute>();
            var guildOnly       = attr.GuildOnly;
            var permissionGroup = attr.PermissionGroup.ToString();

            return(S.ClassDeclaration(className)
                   .AddBaseListTypes(S.SimpleBaseType(CommandType))
                   .AddMembers(
                       // ICommand.Id
                       S.PropertyDeclaration(StringType, nameof(ICommand.Id))
                       .AddAccessorListAccessors(
                           S.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                           .AddBodyStatements(S.ReturnStatement(S.LiteralExpression(SyntaxKind.StringLiteralExpression, S.Literal(id))))
                           .WithSemicolonToken(S.Token(SyntaxKind.SemicolonToken))
                           )
                       .AddModifiers(S.Token(SyntaxKind.PublicKeyword)),

                       // ICommand.Aliases
                       S.PropertyDeclaration(ReadOnlyStringList, nameof(ICommand.Aliases))
                       .AddAccessorListAccessors(
                           S.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                           .AddBodyStatements(S.ReturnStatement(S.ArrayCreationExpression(
                                                                    S.ArrayType(StringType)
                                                                    .WithRankSpecifiers(S.SingletonList(S.ArrayRankSpecifier(S.SingletonSeparatedList <ExpressionSyntax>(S.OmittedArraySizeExpression())))),
                                                                    S.InitializerExpression(SyntaxKind.ArrayInitializerExpression,
                                                                                            new SeparatedSyntaxList <ExpressionSyntax>()
                                                                                            .AddRange(aliases.Select(s => S.LiteralExpression(SyntaxKind.StringLiteralExpression, S.Literal(s))))))))
                           .WithSemicolonToken(S.Token(SyntaxKind.SemicolonToken))
                           )
                       .AddModifiers(S.Token(SyntaxKind.PublicKeyword)),

                       // ICommand.Module
                       S.PropertyDeclaration(StringType, nameof(ICommand.Module))
                       .AddAccessorListAccessors(
                           S.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                           .AddBodyStatements(S.ReturnStatement(S.LiteralExpression(SyntaxKind.StringLiteralExpression, S.Literal(moduleName))))
                           .WithSemicolonToken(S.Token(SyntaxKind.SemicolonToken))
                           )
                       .AddModifiers(S.Token(SyntaxKind.PublicKeyword)),

                       // ICommand.Permission
                       S.PropertyDeclaration(StringType, nameof(ICommand.Permission))
                       .AddAccessorListAccessors(
                           S.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                           .AddBodyStatements(S.ReturnStatement(S.LiteralExpression(SyntaxKind.StringLiteralExpression, S.Literal(permission))))
                           .WithSemicolonToken(S.Token(SyntaxKind.SemicolonToken))
                           )
                       .AddModifiers(S.Token(SyntaxKind.PublicKeyword)),

                       // ICommand.PermissionGroup
                       S.PropertyDeclaration(S.ParseName(nameof(PermissionGroup)), nameof(ICommand.PermissionGroup))
                       .AddAccessorListAccessors(
                           S.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                           .AddBodyStatements(S.ReturnStatement(S.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, S.IdentifierName(nameof(PermissionGroup)), S.IdentifierName(permissionGroup))))
                           .WithSemicolonToken(S.Token(SyntaxKind.SemicolonToken))
                           )
                       .AddModifiers(S.Token(SyntaxKind.PublicKeyword)),

                       // ICommand.GuildOnly
                       S.PropertyDeclaration(BoolType, nameof(ICommand.GuildOnly))
                       .AddAccessorListAccessors(
                           S.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                           .AddBodyStatements(S.ReturnStatement(S.LiteralExpression(guildOnly ? SyntaxKind.TrueLiteralExpression : SyntaxKind.FalseLiteralExpression)))
                           .WithSemicolonToken(S.Token(SyntaxKind.SemicolonToken))
                           )
                       .AddModifiers(S.Token(SyntaxKind.PublicKeyword)),

                       // ICommand.ExecuteAsync
                       S.MethodDeclaration(TaskType, nameof(ICommand.ExecuteAsync))
                       .AddModifiers(S.Token(SyntaxKind.PublicKeyword), S.Token(SyntaxKind.AsyncKeyword))
                       .AddParameterListParameters(Parameter(ArgumentContext, MessageContextType))
                       .AddBodyStatements(
                           S.ExpressionStatement(InvokeCommand(moduleType, method))
                           )
                       ));
        }
Пример #13
0
        IEnumerable <MemberDeclarationSyntax> CreateConstructors()
        {
            SyntaxToken typeName = Symbols.GetNameSyntaxToken(Type);

            if (Type.Initializer != null)
            {
                yield return(SF.ConstructorDeclaration
                             (
                                 SF.List <AttributeListSyntax>(),
                                 SF.TokenList(SF.Token(
                                                  Type.IsAbstract || Type.Initializer.IsProtected
                            ? SyntaxKind.ProtectedKeyword
                            : SyntaxKind.PublicKeyword
                                                  )),
                                 typeName,
                                 Type.Initializer.GetParameterListSyntax(Namespaces, Symbols),
                                 SF.ConstructorInitializer
                                 (
                                     SyntaxKind.BaseConstructorInitializer,
                                     SF.ArgumentList(
                                         SF.SeparatedList(new[]
                {
                    SF.Argument(
                        SF.ObjectCreationExpression(
                            SF.Token(SyntaxKind.NewKeyword),
                            SF.ParseTypeName("DeputyProps"),
                            SF.ArgumentList(SF.SeparatedList(
                                                new[] { GetBaseArgument() }
                                                )),
                            null
                            )
                        )
                })
                                         )
                                 ),
                                 SF.Block(),
                                 null
                             ));
            }

            yield return(SF.ConstructorDeclaration
                         (
                             SF.List <AttributeListSyntax>(),
                             SF.TokenList(SF.Token(SyntaxKind.ProtectedKeyword)),
                             typeName,
                             SF.ParseParameterList("(ByRefValue reference)"),
                             SF.ConstructorInitializer
                             (
                                 SyntaxKind.BaseConstructorInitializer,
                                 SF.ParseArgumentList("(reference)")
                             ),
                             SF.Block(),
                             null
                         ));

            // This constructor allows child classes to supply their own parameter lists. It is always protected.
            yield return(SF.ConstructorDeclaration
                         (
                             SF.List <AttributeListSyntax>(),
                             SF.TokenList(SF.Token(SyntaxKind.ProtectedKeyword)),
                             typeName,
                             SF.ParseParameterList("(DeputyProps props)"),
                             SF.ConstructorInitializer
                             (
                                 SyntaxKind.BaseConstructorInitializer,
                                 SF.ParseArgumentList("(props)")
                             ),
                             SF.Block(),
                             null
                         ));

            ArgumentSyntax GetBaseArgument()
            {
                var deputyArguments = (Type.Initializer.Parameters ?? Enumerable.Empty <Parameter>())
                                      .Select(p => Symbols.GetNameSyntaxToken(p))
                                      .Select(i => SF.IdentifierName(i));

                // In C#, arrays of reference types are covariant. Because of this, passing a string[]
                // to a method that takes `params object[] args` will interperet the string array *as*
                // args, rather than as args' first element. To workaround with, we remove the params
                // keyword from DeputyBase's constructor, and always explicitly create an array of
                // objects when calling it.
                return(SF.Argument(
                           SF.ArrayCreationExpression(
                               SF.Token(SyntaxKind.NewKeyword),
                               SF.ArrayType(SF.ParseTypeName("object[]")),
                               SF.InitializerExpression(
                                   SyntaxKind.ArrayInitializerExpression,
                                   SF.SeparatedList <ExpressionSyntax>(deputyArguments)
                                   )
                               )
                           ));
            }
        }