Ejemplo n.º 1
0
        private SyntaxNode VisitQueryMethodLambdaExpresssion(LambdaExpressionSyntax lambda)
        {
            queryMethodCtx.Current.InLambdaExpression = true;
            SyntaxNode res;

            if (queryMethodCtx.Current.IsDynamicMethod)
            {
                //注意处理行差
                var args = new SeparatedSyntaxList <ArgumentSyntax>();
                if (lambda.Body is AnonymousObjectCreationExpressionSyntax aoc)
                {
                    //转换Lambda表达式为运行时Lambda表达式
                    //eg: t=>new {t.Id, t.Name} 转换为 r=> new {Id=r.GetInt(0), Name=r.GetString(1)}
                    var sb = StringBuilderCache.Acquire();
                    sb.Append("r => new {");
                    for (int i = 0; i < aoc.Initializers.Count; i++)
                    {
                        if (i != 0)
                        {
                            sb.Append(',');
                        }
                        var initializer = aoc.Initializers[i];
                        if (initializer.NameEquals != null)
                        {
                            sb.Append(initializer.NameEquals.Name.Identifier.ValueText);
                        }
                        else
                        {
                            sb.Append(((MemberAccessExpressionSyntax)initializer.Expression).Name.Identifier.ValueText);
                        }
                        sb.Append("=r.Get");
                        var expSymbol  = SemanticModel.GetSymbolInfo(initializer.Expression).Symbol;
                        var expType    = TypeHelper.GetSymbolType(expSymbol);
                        var typeString = TypeHelper.GetEntityMemberTypeString(expType, out bool isNullable);
                        if (isNullable)
                        {
                            sb.Append("Nullable");
                        }
                        sb.Append(typeString);
                        sb.Append('(');
                        sb.Append(i);
                        sb.Append(')');
                    }
                    sb.Append('}');
                    //转换为参数并加入参数列表
                    args = args.Add(SyntaxFactory.Argument(
                                        SyntaxFactory.ParseExpression(StringBuilderCache.GetStringAndRelease(sb))
                                        ));

                    //处理selectItems参数
                    for (int i = 0; i < aoc.Initializers.Count; i++)
                    {
                        var initializer   = aoc.Initializers[i];
                        var argExpression = (ExpressionSyntax)initializer.Expression.Accept(this);
                        if (initializer.NameEquals != null) //TODO:***检查是否还需要转换为SelectAs("XXX"),因前面已按序号获取
                        {
                            var selectAsMethodName = (SimpleNameSyntax)SyntaxFactory.ParseName("SelectAs");
                            var selectAsMethod     = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, argExpression, selectAsMethodName);
                            var selectAsArgs       = SyntaxFactory.ParseArgumentList(string.Format("(\"{0}\")", initializer.NameEquals.Name.Identifier.ValueText));
                            argExpression = SyntaxFactory.InvocationExpression(selectAsMethod, selectAsArgs);
                        }
                        var arg = SyntaxFactory.Argument(argExpression);
                        //最后一个参数补body所有行差
                        if (i == aoc.Initializers.Count - 1)
                        {
                            var lineSpan = lambda.Body.GetLocation().GetLineSpan();
                            var lineDiff = lineSpan.EndLinePosition.Line - lineSpan.StartLinePosition.Line;
                            if (lineDiff > 0)
                            {
                                arg = arg.WithTrailingTrivia(SyntaxFactory.Whitespace(new string('\n', lineDiff)));
                            }
                        }
                        args = args.Add(arg);
                    }
                }
                else if (lambda.Body is MemberAccessExpressionSyntax ma)
                {
                    //转换Lambda表达式为运行时Lambda表达式
                    //eg: t=> t.Name 转换为 r=> r.GetString(0)
                    var sb = StringBuilderCache.Acquire();
                    sb.Append("r => r.Get");
                    var expSymbol  = SemanticModel.GetSymbolInfo(ma).Symbol;
                    var expType    = TypeHelper.GetSymbolType(expSymbol);
                    var typeString = TypeHelper.GetEntityMemberTypeString(expType, out bool isNullable);
                    if (isNullable)
                    {
                        sb.Append("Nullable");
                    }
                    sb.Append(typeString);
                    sb.Append("(0)");
                    //转换为参数并加入参数列表
                    args = args.Add(SyntaxFactory.Argument(
                                        SyntaxFactory.ParseExpression(StringBuilderCache.GetStringAndRelease(sb))
                                        ));

                    //处理selectItems参数
                    var argExpression = (ExpressionSyntax)ma.Accept(this);
                    args = args.Add(SyntaxFactory.Argument(argExpression).WithTriviaFrom(ma));
                }
                else
                {
                    throw new NotImplementedException($"动态查询方法的第一个参数[{lambda.Body.GetType().Name}]暂未实现");
                }

                res = SyntaxFactory.ArgumentList(args);
            }
            else if (queryMethodCtx.Current.MethodName == TypeHelper.SqlQueryToScalarMethod)
            {
                var args          = new SeparatedSyntaxList <ArgumentSyntax>();
                var argExpression = (ExpressionSyntax)lambda.Body.Accept(this);
                var arg           = SyntaxFactory.Argument(argExpression);
                args = args.Add(arg);
                res  = SyntaxFactory.ArgumentList(args);
            }
            else
            {
                res = Visit(lambda.Body);
            }

            queryMethodCtx.Current.InLambdaExpression = false;
            return(res);
        }
Ejemplo n.º 2
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            var diagnostic = context.Diagnostics.First();

            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            var syntaxNode = (ExpressionSyntax)root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);

            var container = Utils.GetContainingFunction(syntaxNode);

            if (container.BlockOrExpression == null)
            {
                return;
            }

            var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

            var enclosingSymbol = semanticModel.GetEnclosingSymbol(diagnostic.Location.SourceSpan.Start, context.CancellationToken);

            if (enclosingSymbol == null)
            {
                return;
            }

            bool convertToAsync = !container.IsAsync && Utils.HasAsyncCompatibleReturnType(enclosingSymbol as IMethodSymbol);

            if (convertToAsync)
            {
                // We don't support this yet, and we don't want to take the sync method path in this case.
                // The user will have to fix this themselves.
                return;
            }

            Regex lookupKey = (container.IsAsync || convertToAsync)
                ? CommonInterest.FileNamePatternForMethodsThatSwitchToMainThread
                : CommonInterest.FileNamePatternForMethodsThatAssertMainThread;

            string[] options = diagnostic.Properties[lookupKey.ToString()].Split('\n');
            if (options.Length > 0)
            {
                // For any symbol lookups, we want to consider the position of the very first statement in the block.
                int positionForLookup = container.BlockOrExpression.GetLocation().SourceSpan.Start + 1;

                var cancellationTokenSymbol = new Lazy <ISymbol>(() => semanticModel.LookupSymbols(positionForLookup)
                                                                 .Where(s => (s.IsStatic || !enclosingSymbol.IsStatic) && s.CanBeReferencedByName && IsSymbolTheRightType(s, nameof(CancellationToken), Namespaces.SystemThreading))
                                                                 .OrderBy(s => s.ContainingSymbol.Equals(enclosingSymbol) ? 1 : s.ContainingType.Equals(enclosingSymbol.ContainingType) ? 2 : 3) // prefer locality
                                                                 .FirstOrDefault());
                foreach (var option in options)
                {
                    var(fullTypeName, methodName) = SplitOffLastElement(option);
                    var(ns, leafTypeName)         = SplitOffLastElement(fullTypeName);
                    string[] namespaces = ns?.Split('.');
                    if (fullTypeName == null)
                    {
                        continue;
                    }

                    var proposedType = semanticModel.Compilation.GetTypeByMetadataName(fullTypeName);

                    // We're looking for methods that either require no parameters,
                    // or (if we have one to give) that have just one parameter that is a CancellationToken.
                    var proposedMethod = proposedType?.GetMembers(methodName).OfType <IMethodSymbol>()
                                         .FirstOrDefault(m => !m.Parameters.Any(p => !p.HasExplicitDefaultValue) ||
                                                         (cancellationTokenSymbol.Value != null && m.Parameters.Length == 1 && IsCancellationTokenParameter(m.Parameters[0])));
                    if (proposedMethod == null)
                    {
                        // We can't find it, so don't offer to use it.
                        continue;
                    }

                    if (proposedMethod.IsStatic)
                    {
                        OfferFix(option);
                    }
                    else
                    {
                        // Search fields on the declaring type.
                        // Consider local variables too, if they're captured in a closure from some surrounding code block
                        // such that they would presumably be initialized by the time the first statement in our own code block runs.
                        ITypeSymbol enclosingTypeSymbol = enclosingSymbol as ITypeSymbol ?? enclosingSymbol.ContainingType;
                        if (enclosingTypeSymbol != null)
                        {
                            var candidateMembers = from symbol in semanticModel.LookupSymbols(positionForLookup, enclosingTypeSymbol)
                                                   where symbol.IsStatic || !enclosingSymbol.IsStatic
                                                   where IsSymbolTheRightType(symbol, leafTypeName, namespaces)
                                                   select symbol;
                            foreach (var candidate in candidateMembers)
                            {
                                OfferFix($"{candidate.Name}.{methodName}");
                            }
                        }

                        // Find static fields/properties that return the matching type from other public, non-generic types.
                        var candidateStatics = from offering in semanticModel.LookupStaticMembers(positionForLookup).OfType <ITypeSymbol>()
                                               from symbol in offering.GetMembers()
                                               where symbol.IsStatic && symbol.CanBeReferencedByName && IsSymbolTheRightType(symbol, leafTypeName, namespaces)
                                               select symbol;
                        foreach (var candidate in candidateStatics)
                        {
                            OfferFix($"{candidate.ContainingNamespace}.{candidate.ContainingType.Name}.{candidate.Name}.{methodName}");
                        }
                    }

                    void OfferFix(string fullyQualifiedMethod)
                    {
                        context.RegisterCodeFix(CodeAction.Create($"Add call to {fullyQualifiedMethod}", ct => Fix(fullyQualifiedMethod, proposedMethod, cancellationTokenSymbol, ct), fullyQualifiedMethod), context.Diagnostics);
                    }
                }
            }

            bool IsSymbolTheRightType(ISymbol symbol, string typeName, IReadOnlyList <string> namespaces)
            {
                var fieldSymbol     = symbol as IFieldSymbol;
                var propertySymbol  = symbol as IPropertySymbol;
                var parameterSymbol = symbol as IParameterSymbol;
                var localSymbol     = symbol as ILocalSymbol;
                var memberType      = fieldSymbol?.Type ?? propertySymbol?.Type ?? parameterSymbol?.Type ?? localSymbol?.Type;

                return(memberType?.Name == typeName && memberType.BelongsToNamespace(namespaces));
            }

            Task <Document> Fix(string fullyQualifiedMethod, IMethodSymbol methodSymbol, Lazy <ISymbol> cancellationTokenSymbol, CancellationToken cancellationToken)
            {
                int typeAndMethodDelimiterIndex    = fullyQualifiedMethod.LastIndexOf('.');
                IdentifierNameSyntax methodName    = SyntaxFactory.IdentifierName(fullyQualifiedMethod.Substring(typeAndMethodDelimiterIndex + 1));
                ExpressionSyntax     invokedMethod = Utils.MemberAccess(fullyQualifiedMethod.Substring(0, typeAndMethodDelimiterIndex).Split('.'), methodName);
                var invocationExpression           = SyntaxFactory.InvocationExpression(invokedMethod);
                var cancellationTokenParameter     = methodSymbol.Parameters.FirstOrDefault(IsCancellationTokenParameter);

                if (cancellationTokenParameter != null && cancellationTokenSymbol.Value != null)
                {
                    var arg = SyntaxFactory.Argument(SyntaxFactory.IdentifierName(cancellationTokenSymbol.Value.Name));
                    if (methodSymbol.Parameters.IndexOf(cancellationTokenParameter) > 0)
                    {
                        arg = arg.WithNameColon(SyntaxFactory.NameColon(SyntaxFactory.IdentifierName(cancellationTokenParameter.Name)));
                    }

                    invocationExpression = invocationExpression.AddArgumentListArguments(arg);
                }

                ExpressionSyntax awaitExpression = container.IsAsync ? SyntaxFactory.AwaitExpression(invocationExpression) : null;
                var addedStatement = SyntaxFactory.ExpressionStatement(awaitExpression ?? invocationExpression)
                                     .WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation);
                var initialBlockSyntax = container.BlockOrExpression as BlockSyntax;

                if (initialBlockSyntax == null)
                {
                    initialBlockSyntax = SyntaxFactory.Block(SyntaxFactory.ReturnStatement((ExpressionSyntax)container.BlockOrExpression))
                                         .WithAdditionalAnnotations(Formatter.Annotation);
                }

                var newBlock = initialBlockSyntax.WithStatements(initialBlockSyntax.Statements.Insert(0, addedStatement));

                return(Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(container.BlockOrExpression, newBlock))));
            }

            bool IsCancellationTokenParameter(IParameterSymbol parameterSymbol) => parameterSymbol.Type.Name == nameof(CancellationToken) && parameterSymbol.Type.BelongsToNamespace(Namespaces.SystemThreading);
        }
        public ExpressionSyntax EmitValueReference(object value)
        {
            var id = AddObject(value);

            return(SyntaxFactory.ElementAccessExpression(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                                              ParseTypeName(typeof(DefaultViewCompilerCodeEmitter)),
                                                                                              SyntaxFactory.IdentifierName(nameof(_ViewImmutableObjects))),
                                                         SyntaxFactory.BracketedArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(EmitValue(id))))));
        }
Ejemplo n.º 4
0
 internal static ExpressionSyntax OptionalFor(ExpressionSyntax expression)
 {
     return(SyntaxFactory.InvocationExpression(
                SyntaxFactory.MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    SyntaxFactory.QualifiedName(
                        SyntaxFactory.IdentifierName(nameof(ImmutableObjectGraph)),
                        SyntaxFactory.IdentifierName(nameof(ImmutableObjectGraph.Optional))),
                    SyntaxFactory.IdentifierName(nameof(ImmutableObjectGraph.Optional.For))),
                SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(expression)))));
 }
        private static async Task <Document> UseCollectionSizeAssertionAsync(Document document, InvocationExpressionSyntax invocation, string replacementMethod, CancellationToken cancellationToken)
        {
            var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);

            var memberAccess = (MemberAccessExpressionSyntax)invocation.Expression;
            var expression   = GetExpressionSyntax(invocation);

            editor.ReplaceNode(invocation,
                               invocation.WithArgumentList(invocation.ArgumentList.WithArguments(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(expression))))
                               .WithExpression(memberAccess.WithName(SyntaxFactory.IdentifierName(replacementMethod))));
            return(editor.GetChangedDocument());
        }
Ejemplo n.º 6
0
 public static InvocationExpressionSyntax Invoke(this ExpressionSyntax target, params ExpressionSyntax[] arguments)
 {
     return(target.Invoke(arguments.Select(x => SyntaxFactory.Argument(x)).ToArray()));
 }
Ejemplo n.º 7
0
 internal static InvocationExpressionSyntax ToList(ExpressionSyntax expression)
 {
     return(SyntaxFactory.InvocationExpression(
                // System.Linq.Enumerable.ToList
                SyntaxFactory.MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    SyntaxFactory.QualifiedName(
                        SyntaxFactory.QualifiedName(
                            SyntaxFactory.IdentifierName(nameof(System)),
                            SyntaxFactory.IdentifierName(nameof(System.Linq))),
                        SyntaxFactory.IdentifierName(nameof(Enumerable))),
                    SyntaxFactory.IdentifierName(nameof(Enumerable.ToList))),
                SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(expression)))));
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Generates the multipart content statements.
        /// </summary>
        /// <param name="curlOptions">The curl options.</param>
        /// <returns>Collection of <see cref="StatementSyntax"/>.</returns>
        /// <remarks>
        /// var multipartContent = new MultipartFormDataContent();
        /// multipartContent.Add(new StringContent("John"), "name");
        /// multipartContent.Add(new ByteArrayContent(File.ReadAllBytes("D:\\text.txt")), "shoesize", Path.GetFileName("D:\\text.txt"));
        /// request.Content = multipartContent;
        /// </remarks>
        private IEnumerable <StatementSyntax> CreateMultipartContentStatements(CurlOptions curlOptions)
        {
            var statements = new LinkedList <StatementSyntax>();

            const string MultipartVariableName  = "multipartContent";
            const string MultipartAddMethodName = "Add";

            statements.AddLast(
                SyntaxFactory.LocalDeclarationStatement(
                    RoslynExtensions.CreateVariableFromNewObjectExpression(
                        MultipartVariableName,
                        nameof(MultipartFormDataContent))));

            int fileCounter = 1;

            foreach (var data in curlOptions.FormData)
            {
                StatementSyntax addStatement;
                if (data.Type == UploadDataType.Inline)
                {
                    var contentExpression = RoslynExtensions.CreateObjectCreationExpression(
                        nameof(StringContent),
                        RoslynExtensions.CreateStringLiteralArgument(data.Content));

                    addStatement = SyntaxFactory.ExpressionStatement(
                        RoslynExtensions.CreateInvocationExpression(
                            MultipartVariableName,
                            MultipartAddMethodName,
                            SyntaxFactory.Argument(contentExpression),
                            RoslynExtensions.CreateStringLiteralArgument(data.Name)));
                }
                else if (data.Type == UploadDataType.BinaryFile)
                {
                    var getFileNameArgument = string.IsNullOrEmpty(data.FileName)
                                                  ? SyntaxFactory.Argument(
                        RoslynExtensions.CreateInvocationExpression(
                            nameof(Path),
                            nameof(Path.GetFileName),
                            RoslynExtensions.CreateStringLiteralArgument(data.Content)))
                                                  : RoslynExtensions.CreateStringLiteralArgument(data.FileName);

                    // If the file has content type, we should add it to ByteArrayContent headers
                    var contentExpression = CreateNewByteArrayContentExpression(data.Content);
                    ExpressionSyntax contentArgumentExpression;
                    if (string.IsNullOrEmpty(data.ContentType))
                    {
                        contentArgumentExpression = contentExpression;
                    }
                    else
                    {
                        var byteArrayVariableName          = "file" + fileCounter;
                        var byteArrayContentInitialization = RoslynExtensions.CreateVariableInitializationExpression(byteArrayVariableName, contentExpression);
                        statements.AddLast(SyntaxFactory.LocalDeclarationStatement(byteArrayContentInitialization));
                        statements.AddLast(
                            SyntaxFactory.ExpressionStatement(
                                RoslynExtensions.CreateInvocationExpression(
                                    byteArrayVariableName,
                                    "Headers",
                                    "Add",
                                    RoslynExtensions.CreateStringLiteralArgument("Content-Type"),
                                    RoslynExtensions.CreateStringLiteralArgument(data.ContentType))));
                        contentArgumentExpression = SyntaxFactory.IdentifierName(byteArrayVariableName);
                    }

                    addStatement = SyntaxFactory.ExpressionStatement(
                        RoslynExtensions.CreateInvocationExpression(
                            MultipartVariableName,
                            MultipartAddMethodName,
                            SyntaxFactory.Argument(contentArgumentExpression),
                            RoslynExtensions.CreateStringLiteralArgument(data.Name),
                            getFileNameArgument));
                }
                else
                {
                    var contentExpression = RoslynExtensions.CreateObjectCreationExpression(
                        nameof(StringContent),
                        SyntaxFactory.Argument(CreateFileReadAllTextExpression(data.Content)));

                    addStatement = SyntaxFactory.ExpressionStatement(
                        RoslynExtensions.CreateInvocationExpression(
                            MultipartVariableName,
                            MultipartAddMethodName,
                            SyntaxFactory.Argument(contentExpression),
                            RoslynExtensions.CreateStringLiteralArgument(data.Name)));
                }

                statements.AddLast(addStatement);
            }

            statements.AddLast(SyntaxFactory.ExpressionStatement(
                                   RoslynExtensions.CreateMemberAssignmentExpression(
                                       RequestVariableName,
                                       RequestContentPropertyName,
                                       SyntaxFactory.IdentifierName(MultipartVariableName))));

            statements.TryAppendWhiteSpaceAtEnd();

            return(statements);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Generate the HttpRequestMessage using statements with statements inside the using blocks.
        /// </summary>
        /// <param name="curlOptions">The curl options.</param>
        /// <returns>Collection of <see cref="UsingStatementSyntax"/>.</returns>
        /// <remarks>
        /// using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://github.com/"))
        /// {
        ///     var response = await httpClient.SendAsync(request);
        /// }
        /// </remarks>
        private IEnumerable <UsingStatementSyntax> CreateRequestUsingStatements(CurlOptions curlOptions)
        {
            var innerBlock = SyntaxFactory.Block();

            var methodNameArgument = RoslynExtensions.CreateStringLiteralArgument(curlOptions.HttpMethod);
            var httpMethodArgument = RoslynExtensions.CreateObjectCreationExpression(nameof(HttpMethod), methodNameArgument);

            var urlArgument           = RoslynExtensions.CreateStringLiteralArgument(curlOptions.GetFullUrl());
            var requestUsingStatement = RoslynExtensions.CreateUsingStatement(
                RequestVariableName,
                nameof(HttpRequestMessage),
                SyntaxFactory.Argument(httpMethodArgument),
                urlArgument);

            var statements = CreateHeaderAssignmentStatements(curlOptions);

            innerBlock = innerBlock.AddStatements(statements.ToArray());

            if (!string.IsNullOrEmpty(curlOptions.UserPasswordPair))
            {
                var basicAuthorizationStatements = CreateBasicAuthorizationStatements(curlOptions);
                innerBlock = innerBlock.AddStatements(basicAuthorizationStatements.ToArray());
            }

            var requestInnerBlocks = new LinkedList <UsingStatementSyntax>();

            if (curlOptions.HasDataPayload && !curlOptions.ForceGet)
            {
                var assignmentExpression = CreateStringContentAssignmentStatement(curlOptions);
                requestInnerBlocks.AddLast(
                    requestUsingStatement.WithStatement(innerBlock.AddStatements(assignmentExpression.ToArray())));
            }
            else if (curlOptions.HasFormPayload)
            {
                var multipartContentStatements = CreateMultipartContentStatements(curlOptions);
                requestInnerBlocks.AddLast(
                    requestUsingStatement.WithStatement(innerBlock.AddStatements(multipartContentStatements.ToArray())));
            }
            else if (curlOptions.HasFilePayload)
            {
                foreach (var file in curlOptions.UploadFiles)
                {
                    // NOTE that you must use a trailing / on the last directory to really prove to
                    // Curl that there is no file name or curl will think that your last directory name is the remote file name to use.
                    if (!string.IsNullOrEmpty(curlOptions.Url.PathAndQuery) &&
                        curlOptions.Url.PathAndQuery.EndsWith('/'))
                    {
                        var objectCreationExpressionSyntaxs = requestUsingStatement.DescendantNodes()
                                                              .OfType <ObjectCreationExpressionSyntax>()
                                                              .First(
                            t => t.Type is IdentifierNameSyntax identifier &&
                            identifier.Identifier.ValueText == nameof(HttpRequestMessage));

                        var s = objectCreationExpressionSyntaxs.ArgumentList.Arguments.Last();

                        requestUsingStatement = requestUsingStatement.ReplaceNode(
                            s,
                            RoslynExtensions.CreateStringLiteralArgument(curlOptions.GetUrlForFileUpload(file).ToString()));
                    }

                    var byteArrayContentExpression = CreateNewByteArrayContentExpression(file);
                    requestInnerBlocks.AddLast(requestUsingStatement.WithStatement(innerBlock.AddStatements(
                                                                                       SyntaxFactory.ExpressionStatement(
                                                                                           RoslynExtensions.CreateMemberAssignmentExpression(
                                                                                               RequestVariableName,
                                                                                               RequestContentPropertyName,
                                                                                               byteArrayContentExpression))
                                                                                       .AppendWhiteSpace())));
                }
            }

            var sendStatement = CreateSendStatement();

            if (!requestInnerBlocks.Any())
            {
                return(new List <UsingStatementSyntax> {
                    requestUsingStatement.WithStatement(innerBlock.AddStatements(sendStatement))
                });
            }

            return(requestInnerBlocks.Select(i => i.WithStatement(((BlockSyntax)i.Statement).AddStatements(sendStatement))));
        }
Ejemplo n.º 10
0
            private void ImplementSortedChildrenInterface()
            {
                this.baseTypes.Add(SyntaxFactory.SimpleBaseType(Syntax.GetTypeSyntax(typeof(IRecursiveParentWithSortedChildren))));

                // int IRecursiveParentWithSortedChildren.Compare(IRecursiveType first, IRecursiveType second)
                var firstParameterName  = SyntaxFactory.IdentifierName("first");
                var secondParameterName = SyntaxFactory.IdentifierName("second");

                this.innerMembers.Add(SyntaxFactory.MethodDeclaration(
                                          SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)),
                                          nameof(IRecursiveParentWithSortedChildren.Compare))
                                      .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(SyntaxFactory.IdentifierName(nameof(IRecursiveParentWithSortedChildren))))
                                      .AddParameterListParameters(
                                          SyntaxFactory.Parameter(firstParameterName.Identifier).WithType(Syntax.GetTypeSyntax(typeof(IRecursiveType))),
                                          SyntaxFactory.Parameter(secondParameterName.Identifier).WithType(Syntax.GetTypeSyntax(typeof(IRecursiveType))))
                                      .WithBody(SyntaxFactory.Block(
                                                    // return this.Children.KeyComparer.Compare((<#= templateType.RecursiveType.TypeName #>)first, (<#= templateType.RecursiveType.TypeName #>)second);
                                                    SyntaxFactory.ReturnStatement(
                                                        SyntaxFactory.InvocationExpression(
                                                            SyntaxFactory.MemberAccessExpression(
                                                                SyntaxKind.SimpleMemberAccessExpression,
                                                                SyntaxFactory.MemberAccessExpression(
                                                                    SyntaxKind.SimpleMemberAccessExpression,
                                                                    Syntax.ThisDot(SyntaxFactory.IdentifierName(this.generator.applyToMetaType.RecursiveField.Name.ToPascalCase())),
                                                                    SyntaxFactory.IdentifierName(nameof(ImmutableSortedSet <int> .KeyComparer))),
                                                                SyntaxFactory.IdentifierName(nameof(IComparer <int> .Compare))),
                                                            SyntaxFactory.ArgumentList(Syntax.JoinSyntaxNodes(SyntaxKind.CommaToken,
                                                                                                              SyntaxFactory.Argument(SyntaxFactory.CastExpression(this.generator.applyToMetaType.RecursiveType.TypeSyntax, firstParameterName)),
                                                                                                              SyntaxFactory.Argument(SyntaxFactory.CastExpression(this.generator.applyToMetaType.RecursiveType.TypeSyntax, secondParameterName)))))))));
            }
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Diagnostic?diagnostic = context.Diagnostics.First();

            SyntaxNode?root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            var syntaxNode = (ExpressionSyntax)root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);

            CSharpUtils.ContainingFunctionData container = CSharpUtils.GetContainingFunction(syntaxNode);
            if (container.BlockOrExpression is null)
            {
                return;
            }

            SemanticModel?semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

            ISymbol?enclosingSymbol = semanticModel.GetEnclosingSymbol(diagnostic.Location.SourceSpan.Start, context.CancellationToken);

            if (enclosingSymbol is null)
            {
                return;
            }

            bool convertToAsync = !container.IsAsync && Utils.HasAsyncCompatibleReturnType(enclosingSymbol as IMethodSymbol);

            if (convertToAsync)
            {
                // We don't support this yet, and we don't want to take the sync method path in this case.
                // The user will have to fix this themselves.
                return;
            }

            Regex lookupKey = (container.IsAsync || convertToAsync)
                ? CommonInterest.FileNamePatternForMethodsThatSwitchToMainThread
                : CommonInterest.FileNamePatternForMethodsThatAssertMainThread;

            string[] options = diagnostic.Properties[lookupKey.ToString()].Split('\n');
            if (options.Length > 0)
            {
                // For any symbol lookups, we want to consider the position of the very first statement in the block.
                int positionForLookup = container.BlockOrExpression.GetLocation().SourceSpan.Start + 1;

                Lazy <ISymbol> cancellationTokenSymbol = new Lazy <ISymbol>(() => Utils.FindCancellationToken(semanticModel, positionForLookup, context.CancellationToken).FirstOrDefault());
                foreach (var option in options)
                {
                    // We're looking for methods that either require no parameters,
                    // or (if we have one to give) that have just one parameter that is a CancellationToken.
                    IMethodSymbol?proposedMethod = Utils.FindMethodGroup(semanticModel, option)
                                                   .FirstOrDefault(m => !m.Parameters.Any(p => !p.HasExplicitDefaultValue) ||
                                                                   (cancellationTokenSymbol.Value is object && m.Parameters.Length == 1 && Utils.IsCancellationTokenParameter(m.Parameters[0])));
                    if (proposedMethod is null)
                    {
                        // We can't find it, so don't offer to use it.
                        continue;
                    }

                    if (proposedMethod.IsStatic)
                    {
                        OfferFix(option);
                    }
                    else
                    {
                        foreach (Tuple <bool, ISymbol>?candidate in Utils.FindInstanceOf(proposedMethod.ContainingType, semanticModel, positionForLookup, context.CancellationToken))
                        {
                            if (candidate.Item1)
                            {
                                OfferFix($"{candidate.Item2.Name}.{proposedMethod.Name}");
                            }
                            else
                            {
                                OfferFix($"{candidate.Item2.ContainingNamespace}.{candidate.Item2.ContainingType.Name}.{candidate.Item2.Name}.{proposedMethod.Name}");
                            }
                        }
                    }

                    void OfferFix(string fullyQualifiedMethod)
                    {
                        context.RegisterCodeFix(CodeAction.Create($"Add call to {fullyQualifiedMethod}", ct => Fix(fullyQualifiedMethod, proposedMethod, cancellationTokenSymbol), fullyQualifiedMethod), context.Diagnostics);
                    }
                }
            }

            Task <Document> Fix(string fullyQualifiedMethod, IMethodSymbol methodSymbol, Lazy <ISymbol> cancellationTokenSymbol)
            {
                int typeAndMethodDelimiterIndex                       = fullyQualifiedMethod.LastIndexOf('.');
                IdentifierNameSyntax       methodName                 = SyntaxFactory.IdentifierName(fullyQualifiedMethod.Substring(typeAndMethodDelimiterIndex + 1));
                ExpressionSyntax           invokedMethod              = CSharpUtils.MemberAccess(fullyQualifiedMethod.Substring(0, typeAndMethodDelimiterIndex).Split('.'), methodName);
                InvocationExpressionSyntax?invocationExpression       = SyntaxFactory.InvocationExpression(invokedMethod);
                IParameterSymbol?          cancellationTokenParameter = methodSymbol.Parameters.FirstOrDefault(Utils.IsCancellationTokenParameter);

                if (cancellationTokenParameter is object && cancellationTokenSymbol.Value is object)
                {
                    ArgumentSyntax?arg = SyntaxFactory.Argument(SyntaxFactory.IdentifierName(cancellationTokenSymbol.Value.Name));
                    if (methodSymbol.Parameters.IndexOf(cancellationTokenParameter) > 0)
                    {
                        arg = arg.WithNameColon(SyntaxFactory.NameColon(SyntaxFactory.IdentifierName(cancellationTokenParameter.Name)));
                    }

                    invocationExpression = invocationExpression.AddArgumentListArguments(arg);
                }

                ExpressionSyntax?         awaitExpression = container.IsAsync ? SyntaxFactory.AwaitExpression(invocationExpression) : null;
                ExpressionStatementSyntax?addedStatement  = SyntaxFactory.ExpressionStatement(awaitExpression ?? invocationExpression)
                                                            .WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation);
                var initialBlockSyntax = container.BlockOrExpression as BlockSyntax;

                if (initialBlockSyntax is null)
                {
                    initialBlockSyntax = SyntaxFactory.Block(SyntaxFactory.ReturnStatement((ExpressionSyntax)container.BlockOrExpression))
                                         .WithAdditionalAnnotations(Formatter.Annotation);
                }

                BlockSyntax?newBlock = initialBlockSyntax.WithStatements(initialBlockSyntax.Statements.Insert(0, addedStatement));

                return(Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(container.BlockOrExpression, newBlock))));
            }
        }
Ejemplo n.º 12
0
            private void ImplementOrderedChildrenInterface()
            {
                // We only need to declare this interface if the children are not sorted,
                // since sorted children merit a derived interface making this redundant.
                if (!this.generator.applyToMetaType.ChildrenAreSorted)
                {
                    this.baseTypes.Add(SyntaxFactory.SimpleBaseType(Syntax.GetTypeSyntax(typeof(IRecursiveParentWithOrderedChildren))));
                }

                // IReadOnlyList<IRecursiveType> IRecursiveParentWithOrderedChildren.Children => this.children;
                this.innerMembers.Add(SyntaxFactory.PropertyDeclaration(
                                          Syntax.IReadOnlyListOf(Syntax.GetTypeSyntax(typeof(IRecursiveType))),
                                          nameof(IRecursiveParentWithOrderedChildren.Children))
                                      .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(SyntaxFactory.IdentifierName(nameof(IRecursiveParentWithOrderedChildren))))
                                      .WithExpressionBody(SyntaxFactory.ArrowExpressionClause(Syntax.ThisDot(SyntaxFactory.IdentifierName(this.generator.applyToMetaType.RecursiveField.Name))))
                                      .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
                                      .AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(DebuggerBrowsableNeverAttribute))));

                // int IRecursiveParentWithOrderedChildren.IndexOf(IRecursiveType value)
                var valueParameterName = SyntaxFactory.IdentifierName("value");

                this.innerMembers.Add(SyntaxFactory.MethodDeclaration(
                                          SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)),
                                          nameof(IRecursiveParentWithOrderedChildren.IndexOf))
                                      .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(SyntaxFactory.IdentifierName(nameof(IRecursiveParentWithOrderedChildren))))
                                      .AddParameterListParameters(SyntaxFactory.Parameter(valueParameterName.Identifier).WithType(Syntax.GetTypeSyntax(typeof(IRecursiveType))))
                                      .WithBody(SyntaxFactory.Block(
                                                    // return this.Children.IndexOf((<#= templateType.RecursiveType.TypeName #>)value);
                                                    SyntaxFactory.ReturnStatement(
                                                        SyntaxFactory.InvocationExpression(
                                                            SyntaxFactory.MemberAccessExpression(
                                                                SyntaxKind.SimpleMemberAccessExpression,
                                                                Syntax.ThisDot(SyntaxFactory.IdentifierName(this.generator.applyToMetaType.RecursiveField.Name.ToPascalCase())),
                                                                SyntaxFactory.IdentifierName(nameof(IList <int> .IndexOf))),
                                                            SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(
                                                                                           SyntaxFactory.Argument(
                                                                                               SyntaxFactory.CastExpression(
                                                                                                   this.generator.applyToMetaType.RecursiveType.TypeSyntax,
                                                                                                   valueParameterName)))))))));
            }
Ejemplo n.º 13
0
            private void ImplementRecursiveParentInterface()
            {
                var irecursiveParentOfT = CreateIRecursiveParentOfTSyntax(GetFullyQualifiedSymbolName(this.generator.applyToMetaType.RecursiveType.TypeSymbol));

                this.baseTypes.Add(SyntaxFactory.SimpleBaseType(irecursiveParentOfT));

                // this.Children;
                var thisDotChildren = Syntax.ThisDot(SyntaxFactory.IdentifierName(this.generator.applyToMetaType.RecursiveField.Name.ToPascalCase()));

                // System.Collections.Generic.IReadOnlyCollection<IRecursiveType> IRecursiveParent.Children
                this.innerMembers.Add(
                    SyntaxFactory.PropertyDeclaration(
                        Syntax.GetTypeSyntax(typeof(IReadOnlyCollection <IRecursiveType>)),
                        nameof(IRecursiveParent.Children))
                    .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(Syntax.GetTypeSyntax(typeof(IRecursiveParent))))
                    .WithExpressionBody(SyntaxFactory.ArrowExpressionClause(thisDotChildren))
                    .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
                    .AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(DebuggerBrowsableNeverAttribute))));

                // public ParentedRecursiveType<TRecursiveParent, TRecursiveType> GetParentedNode(uint identity)
                this.innerMembers.Add(
                    SyntaxFactory.MethodDeclaration(
                        SyntaxFactory.GenericName(nameof(ParentedRecursiveType <IRecursiveParent <IRecursiveType>, IRecursiveType>)).AddTypeArgumentListArguments(
                            this.applyTo.RecursiveParent.TypeSyntax,
                            this.applyTo.RecursiveType.TypeSyntax),
                        nameof(IRecursiveParent.GetParentedNode))
                    .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
                    //.WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(Syntax.GetTypeSyntax(typeof(IRecursiveParent))))
                    .AddParameterListParameters(RequiredIdentityParameter)
                    .WithBody(SyntaxFactory.Block(
                                  // return this.GetParentedNode<TRecursiveParent, TRecursiveType>(identity);
                                  SyntaxFactory.ReturnStatement(
                                      SyntaxFactory.InvocationExpression(
                                          Syntax.ThisDot(SyntaxFactory.GenericName(nameof(RecursiveTypeExtensions.GetParentedNode)).AddTypeArgumentListArguments(
                                                             this.applyTo.RecursiveParent.TypeSyntax,
                                                             this.applyTo.RecursiveType.TypeSyntax)))
                                      .AddArgumentListArguments(SyntaxFactory.Argument(IdentityParameterName))))));

                // ParentedRecursiveType<IRecursiveParent<IRecursiveType>, IRecursiveType> IRecursiveParent.GetParentedNode(<#= templateType.RequiredIdentityField.TypeName #> identity) {
                var parentedVar = SyntaxFactory.IdentifierName("parented");
                var returnType  = Syntax.GetTypeSyntax(typeof(ParentedRecursiveTypeNonGeneric));

                this.innerMembers.Add(
                    SyntaxFactory.MethodDeclaration(
                        returnType,
                        nameof(IRecursiveParent.GetParentedNode))
                    .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(Syntax.GetTypeSyntax(typeof(IRecursiveParent))))
                    .AddParameterListParameters(RequiredIdentityParameter)
                    .WithBody(SyntaxFactory.Block(
                                  // var parented = this.GetParentedNode(identity);
                                  SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(varType).AddVariables(
                                                                              SyntaxFactory.VariableDeclarator(parentedVar.Identifier).WithInitializer(SyntaxFactory.EqualsValueClause(
                                                                                                                                                           SyntaxFactory.InvocationExpression(Syntax.ThisDot(SyntaxFactory.IdentifierName(nameof(RecursiveTypeExtensions.GetParentedNode))))
                                                                                                                                                           .AddArgumentListArguments(SyntaxFactory.Argument(IdentityParameterName)))))),
                                  // return new ParentedRecursiveType<IRecursiveParent<IRecursiveType>, IRecursiveType>(parented.Value, parented.Parent);
                                  SyntaxFactory.ReturnStatement(SyntaxFactory.ObjectCreationExpression(returnType).AddArgumentListArguments(
                                                                    SyntaxFactory.Argument(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, parentedVar, SyntaxFactory.IdentifierName(nameof(ParentedRecursiveTypeNonGeneric.Value)))),
                                                                    SyntaxFactory.Argument(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, parentedVar, SyntaxFactory.IdentifierName(nameof(ParentedRecursiveTypeNonGeneric.Parent)))))))));

                ////System.Collections.Generic.IReadOnlyCollection<<#= templateType.RecursiveType.TypeName #>> IRecursiveParent<<#= templateType.RecursiveType.TypeName #>>.Children
                ////	=> return this.Children;
                this.innerMembers.Add(
                    SyntaxFactory.PropertyDeclaration(
                        Syntax.IReadOnlyCollectionOf(this.generator.applyToMetaType.RecursiveType.TypeSyntax),
                        nameof(IRecursiveParent <IRecursiveType> .Children))
                    .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(irecursiveParentOfT))
                    .WithExpressionBody(SyntaxFactory.ArrowExpressionClause(thisDotChildren))
                    .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
                    .AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(DebuggerBrowsableNeverAttribute))));
            }
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            foreach (var diagnostic in context.Diagnostics)
            {
                var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

                ExpressionSyntax?syntaxNode = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true) as ExpressionSyntax;
                if (syntaxNode is null)
                {
                    continue;
                }

                var container = Utils.GetContainingFunction(syntaxNode);
                if (container.BlockOrExpression == null)
                {
                    return;
                }

                if (!container.IsAsync)
                {
                    if (!(container.Function is MethodDeclarationSyntax || container.Function is AnonymousFunctionExpressionSyntax))
                    {
                        // We don't support converting whatever this is into an async method.
                        return;
                    }
                }

                var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

                var enclosingSymbol = semanticModel.GetEnclosingSymbol(diagnostic.Location.SourceSpan.Start, context.CancellationToken);
                if (enclosingSymbol == null)
                {
                    return;
                }

                var hasReturnValue = ((enclosingSymbol as IMethodSymbol)?.ReturnType as INamedTypeSymbol)?.IsGenericType ?? false;
                var options        = await CommonFixes.ReadMethodsAsync(context, CommonInterest.FileNamePatternForMethodsThatSwitchToMainThread, context.CancellationToken);

                int     positionForLookup       = diagnostic.Location.SourceSpan.Start;
                ISymbol cancellationTokenSymbol = Utils.FindCancellationToken(semanticModel, positionForLookup, context.CancellationToken).FirstOrDefault();
                foreach (var option in options)
                {
                    // We're looking for methods that either require no parameters,
                    // or (if we have one to give) that have just one parameter that is a CancellationToken.
                    var proposedMethod = Utils.FindMethodGroup(semanticModel, option)
                                         .FirstOrDefault(m => !m.Parameters.Any(p => !p.HasExplicitDefaultValue) ||
                                                         (cancellationTokenSymbol != null && m.Parameters.Length == 1 && Utils.IsCancellationTokenParameter(m.Parameters[0])));
                    if (proposedMethod == null)
                    {
                        // We can't find it, so don't offer to use it.
                        continue;
                    }

                    if (proposedMethod.IsStatic)
                    {
                        OfferFix(option.ToString());
                    }
                    else
                    {
                        foreach (var candidate in Utils.FindInstanceOf(proposedMethod.ContainingType, semanticModel, positionForLookup, context.CancellationToken))
                        {
                            if (candidate.Item1)
                            {
                                OfferFix($"{candidate.Item2.Name}.{proposedMethod.Name}");
                            }
                            else
                            {
                                OfferFix($"{candidate.Item2.ContainingNamespace}.{candidate.Item2.ContainingType.Name}.{candidate.Item2.Name}.{proposedMethod.Name}");
                            }
                        }
                    }

                    void OfferFix(string fullyQualifiedMethod)
                    {
                        context.RegisterCodeFix(CodeAction.Create($"Use 'await {fullyQualifiedMethod}'", ct => Fix(fullyQualifiedMethod, proposedMethod, hasReturnValue, ct), fullyQualifiedMethod), context.Diagnostics);
                    }
                }

                async Task <Solution> Fix(string fullyQualifiedMethod, IMethodSymbol methodSymbol, bool hasReturnValue, CancellationToken cancellationToken)
                {
                    var assertionStatementToRemove = syntaxNode !.FirstAncestorOrSelf <StatementSyntax>();

                    int typeAndMethodDelimiterIndex    = fullyQualifiedMethod.LastIndexOf('.');
                    IdentifierNameSyntax methodName    = SyntaxFactory.IdentifierName(fullyQualifiedMethod.Substring(typeAndMethodDelimiterIndex + 1));
                    ExpressionSyntax     invokedMethod = Utils.MemberAccess(fullyQualifiedMethod.Substring(0, typeAndMethodDelimiterIndex).Split('.'), methodName)
                                                         .WithAdditionalAnnotations(Simplifier.Annotation);
                    var invocationExpression       = SyntaxFactory.InvocationExpression(invokedMethod);
                    var cancellationTokenParameter = methodSymbol.Parameters.FirstOrDefault(Utils.IsCancellationTokenParameter);

                    if (cancellationTokenParameter != null && cancellationTokenSymbol != null)
                    {
                        var arg = SyntaxFactory.Argument(SyntaxFactory.IdentifierName(cancellationTokenSymbol.Name));
                        if (methodSymbol.Parameters.IndexOf(cancellationTokenParameter) > 0)
                        {
                            arg = arg.WithNameColon(SyntaxFactory.NameColon(SyntaxFactory.IdentifierName(cancellationTokenParameter.Name)));
                        }

                        invocationExpression = invocationExpression.AddArgumentListArguments(arg);
                    }

                    ExpressionSyntax awaitExpression = SyntaxFactory.AwaitExpression(invocationExpression);
                    var addedStatement = SyntaxFactory.ExpressionStatement(awaitExpression)
                                         .WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation);

                    var methodAnnotation          = new SyntaxAnnotation();
                    CSharpSyntaxNode methodSyntax = container.Function.ReplaceNode(assertionStatementToRemove, addedStatement)
                                                    .WithAdditionalAnnotations(methodAnnotation);
                    Document newDocument   = context.Document.WithSyntaxRoot(root.ReplaceNode(container.Function, methodSyntax));
                    var      newSyntaxRoot = await newDocument.GetSyntaxRootAsync(cancellationToken);

                    methodSyntax = (CSharpSyntaxNode)newSyntaxRoot.GetAnnotatedNodes(methodAnnotation).Single();
                    if (!container.IsAsync)
                    {
                        switch (methodSyntax)
                        {
                        case AnonymousFunctionExpressionSyntax anonFunc:
                            semanticModel = await newDocument.GetSemanticModelAsync(cancellationToken);

                            methodSyntax = FixUtils.MakeMethodAsync(anonFunc, hasReturnValue, semanticModel, cancellationToken);
                            newDocument  = newDocument.WithSyntaxRoot(newSyntaxRoot.ReplaceNode(anonFunc, methodSyntax));
                            break;

                        case MethodDeclarationSyntax methodDecl:
                            (newDocument, methodSyntax) = await FixUtils.MakeMethodAsync(methodDecl, newDocument, cancellationToken);

                            break;
                        }
                    }

                    return(newDocument.Project.Solution);
                }
            }
        }
            public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node)
            {
                var visitedNode = (MethodDeclarationSyntax)base.VisitMethodDeclaration(node);

                if (ReferenceEquals(visitedNode, node) &&
                    _methodsWithOptionOverloads.Contains(node.Identifier.ValueText))
                {
                    // Don't generate methods where the body would call an overload.
                    // The logic is a bit more complicated and there are only
                    // two methods anyway. They can be written out by hand in the
                    // partial class.

                    return(SyntaxFactory.IncompleteMember());
                }

                var returnTypeSymbol = _semanticModel.GetTypeInfo(node.ReturnType).Type as INamedTypeSymbol;

                bool isAsync = returnTypeSymbol != null &&
                               (returnTypeSymbol.Equals(_taskTypeSymbol) || returnTypeSymbol.ConstructedFrom.Equals(_taskOfTTypeSymbol));

                if (isAsync)
                {
                    visitedNode = visitedNode.AddModifiers(SyntaxFactory.Token(SyntaxKind.AsyncKeyword));
                    var invocation = visitedNode.DescendantNodes().OfType <InvocationExpressionSyntax>().First();
                    visitedNode = visitedNode.ReplaceNode(invocation, SyntaxFactory.AwaitExpression(invocation));
                }

                // wrap with try/catch

                visitedNode = visitedNode.WithBody(SyntaxFactory.Block(SyntaxFactory.TryStatement(
                                                                           block: visitedNode.Body,
                                                                           catches: SyntaxFactory.SingletonList(
                                                                               SyntaxFactory.CatchClause()
                                                                               .WithDeclaration(
                                                                                   SyntaxFactory.CatchDeclaration(
                                                                                       SyntaxFactory.IdentifierName("System.Exception"))
                                                                                   .WithIdentifier(
                                                                                       SyntaxFactory.Identifier("ex")))
                                                                               .WithBlock(
                                                                                   SyntaxFactory.Block(
                                                                                       SyntaxFactory.SeparatedList(
                                                                                           new StatementSyntax[]
                {
                    SyntaxFactory.ExpressionStatement(SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName("ProcessException")).AddArgumentListArguments(SyntaxFactory.Argument(SyntaxFactory.IdentifierName("ex")))),
                    SyntaxFactory.ThrowStatement(),
                })))),
                                                                           @finally: null)));

                if (isAsync &&
                    returnTypeSymbol.TypeArguments.FirstOrDefault() is INamedTypeSymbol argumentType &&
                    argumentType.IsGenericType &&
                    _responseTypeSymbols.Contains(argumentType.ConstructedFrom))
                {
                    var awaitSyntax = visitedNode.DescendantNodes().OfType <AwaitExpressionSyntax>().First();
                    visitedNode = visitedNode.ReplaceNode(awaitSyntax, SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName("ProcessResponse")).AddArgumentListArguments(SyntaxFactory.Argument(awaitSyntax)));
                }

                return(visitedNode);
            }
Ejemplo n.º 16
0
        /// <summary>
        /// Generate the statements for HttpClient handler configuration.
        /// </summary>
        /// <param name="curlOptions">The curl options.</param>
        /// <returns>Collection of <see cref="MemberDeclarationSyntax" />.</returns>
        /// <remarks>
        /// var handler = new HttpClientHandler();
        /// handler.UseCookies = false;
        /// </remarks>
        private IEnumerable <MemberDeclarationSyntax> ConfigureHandlerStatements(CurlOptions curlOptions)
        {
            var statementSyntaxs = new LinkedList <MemberDeclarationSyntax>();

            var handlerInitialization = RoslynExtensions.CreateVariableFromNewObjectExpression(
                HandlerVariableName,
                nameof(HttpClientHandler));

            statementSyntaxs.AddLast(
                SyntaxFactory.GlobalStatement(SyntaxFactory.LocalDeclarationStatement(handlerInitialization)));

            if (curlOptions.HasCookies)
            {
                var memberAssignmentExpression = RoslynExtensions.CreateMemberAssignmentExpression(
                    HandlerVariableName,
                    "UseCookies",
                    SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression));
                statementSyntaxs.AddLast(
                    SyntaxFactory.GlobalStatement(SyntaxFactory.ExpressionStatement(memberAssignmentExpression)));
            }

            if (curlOptions.HasProxy && IsSupportedProxy(curlOptions.ProxyUri))
            {
                var memberAssignmentExpression = CreateProxyStatements(curlOptions);

                statementSyntaxs.AddLast(
                    SyntaxFactory.GlobalStatement(SyntaxFactory.ExpressionStatement(memberAssignmentExpression)));
            }

            if (curlOptions.HasCertificate && IsSupportedCertificate(curlOptions.CertificateType))
            {
                var memberAssignmentExpression = RoslynExtensions.CreateMemberAssignmentExpression(
                    HandlerVariableName,
                    "ClientCertificateOptions",
                    RoslynExtensions.CreateMemberAccessExpression("ClientCertificateOption", "Manual"));

                statementSyntaxs.AddLast(
                    SyntaxFactory.GlobalStatement(SyntaxFactory.ExpressionStatement(memberAssignmentExpression)));

                var newCertificateArguments = new LinkedList <ArgumentSyntax>();
                newCertificateArguments.AddLast(RoslynExtensions.CreateStringLiteralArgument(curlOptions.CertificateFileName));
                if (curlOptions.HasCertificatePassword)
                {
                    newCertificateArguments.AddLast(RoslynExtensions.CreateStringLiteralArgument(curlOptions.CertificatePassword));
                }

                var newCertificateExpression = RoslynExtensions.CreateObjectCreationExpression(
                    "X509Certificate2",
                    newCertificateArguments.ToArray());
                var certificateAssignmentExpression = RoslynExtensions.CreateInvocationExpression(
                    HandlerVariableName,
                    "ClientCertificates",
                    "Add",
                    SyntaxFactory.Argument(newCertificateExpression));
                statementSyntaxs.AddLast(
                    SyntaxFactory.GlobalStatement(SyntaxFactory.ExpressionStatement(certificateAssignmentExpression)));
            }

            if (curlOptions.Insecure)
            {
                var parameterListSyntax = RoslynExtensions.CreateParameterListSyntax(
                    "requestMessage",
                    "certificate",
                    "chain",
                    "policyErrors");
                var lambdaExpression = SyntaxFactory.ParenthesizedLambdaExpression(
                    parameterListSyntax,
                    SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression, SyntaxFactory.Token(SyntaxKind.TrueKeyword)));

                statementSyntaxs.AddLast(
                    SyntaxFactory.GlobalStatement(
                        SyntaxFactory.ExpressionStatement(
                            RoslynExtensions.CreateMemberAssignmentExpression(
                                HandlerVariableName,
                                "ServerCertificateCustomValidationCallback",
                                lambdaExpression))));
            }

            statementSyntaxs.TryAppendWhiteSpaceAtEnd();

            return(statementSyntaxs);
        }
Ejemplo n.º 17
0
 public ArgumentBridge(bool value)
 {
     Value = SyntaxFactory.Argument(value
         ? SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression)
         : SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression));
 }
Ejemplo n.º 18
0
        /// <summary>
        /// Generates the string content creation statements.
        /// </summary>
        /// <param name="curlOptions">The curl options.</param>
        /// <returns>Collection of <see cref="StatementSyntax"/>.</returns>
        /// <remarks>
        /// request.Content = new StringContent("{\"status\": \"resolved\"}", Encoding.UTF8, "application/json");
        /// </remarks>
        private IEnumerable <StatementSyntax> CreateStringContentAssignmentStatement(CurlOptions curlOptions)
        {
            var expressions = new LinkedList <ExpressionSyntax>();

            foreach (var data in curlOptions.UploadData)
            {
                if (data.IsUrlEncoded)
                {
                    ExpressionSyntax dataExpression;
                    if (data.IsFile)
                    {
                        dataExpression = CreateFileReadAllTextExpression(data.Content);
                    }
                    else
                    {
                        dataExpression = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(data.Content));
                    }

                    dataExpression = RoslynExtensions.CreateInvocationExpression("Uri", "EscapeDataString", SyntaxFactory.Argument(dataExpression));

                    if (data.HasName)
                    {
                        dataExpression =
                            RoslynExtensions.CreateInterpolatedStringExpression($"{data.Name}=", dataExpression);
                    }

                    expressions.AddLast(dataExpression);

                    continue;
                }

                if (data.Type == UploadDataType.BinaryFile)
                {
                    var readFileExpression = CreateFileReadAllTextExpression(data.Content);
                    expressions.AddLast(readFileExpression);

                    continue;
                }

                if (data.Type == UploadDataType.InlineFile)
                {
                    var readFileExpression = CreateFileReadAllTextExpression(data.Content);
                    var replaceNewLines    = RoslynExtensions.CreateInvocationExpression(
                        "Regex",
                        "Replace",
                        SyntaxFactory.Argument(readFileExpression),
                        RoslynExtensions.CreateStringLiteralArgument(@"(?:\r\n|\n|\r)"),
                        SyntaxFactory.Argument(RoslynExtensions.CreateMemberAccessExpression("string", "Empty")));
                    expressions.AddLast(replaceNewLines);

                    continue;
                }

                expressions.AddLast(
                    SyntaxFactory.LiteralExpression(
                        SyntaxKind.StringLiteralExpression,
                        SyntaxFactory.Literal(data.Content)));
            }

            var            statements = new LinkedList <StatementSyntax>();
            ArgumentSyntax stringContentArgumentSyntax;

            if (expressions.Count > 1)
            {
                var contentListVariableName = "contentList";
                statements.AddLast(
                    SyntaxFactory.LocalDeclarationStatement(
                        RoslynExtensions.CreateVariableFromNewObjectExpression(contentListVariableName, "List<string>")));

                foreach (var expression in expressions)
                {
                    statements.AddLast(
                        SyntaxFactory.ExpressionStatement(
                            RoslynExtensions.CreateInvocationExpression(
                                contentListVariableName,
                                "Add",
                                SyntaxFactory.Argument(expression))));
                }

                stringContentArgumentSyntax = SyntaxFactory.Argument(
                    RoslynExtensions.CreateInvocationExpression(
                        "string",
                        "Join",
                        RoslynExtensions.CreateStringLiteralArgument("&"),
                        SyntaxFactory.Argument(SyntaxFactory.IdentifierName(contentListVariableName))));
            }
            else
            {
                stringContentArgumentSyntax = SyntaxFactory.Argument(expressions.First.Value);
            }

            var stringContentCreation = CreateStringContentCreation(
                stringContentArgumentSyntax,
                curlOptions);

            statements.AddLast(
                SyntaxFactory.ExpressionStatement(
                    RoslynExtensions.CreateMemberAssignmentExpression(
                        RequestVariableName,
                        RequestContentPropertyName,
                        stringContentCreation)));

            statements.TryAppendWhiteSpaceAtEnd();

            return(statements);
        }
Ejemplo n.º 19
0
 public static ObjectCreationExpressionSyntax New(this TypeSyntax type, params ExpressionSyntax[] arguments)
 {
     return(SyntaxFactory.ObjectCreationExpression(type)
            .WithArgumentList(SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(arguments.Select(x => SyntaxFactory.Argument(x)), arguments.Skip(1).Select(_ => SyntaxFactory.Token(SyntaxKind.CommaToken))))));
 }
        protected static InvocationExpressionSyntax GetConstraintExpression(string constraintString, ExpressionSyntax expected)
        {
            if (expected == null)
            {
                return(null);
            }

            return(SyntaxFactory.InvocationExpression(
                       SyntaxFactory.ParseExpression(constraintString),
                       SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(expected)))));
        }
Ejemplo n.º 21
0
 internal static InvocationExpressionSyntax OptionalGetValueOrDefault(ExpressionSyntax optionalOfTExpression, ExpressionSyntax defaultValue)
 {
     return(SyntaxFactory.InvocationExpression(
                SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, optionalOfTExpression, SyntaxFactory.IdentifierName(nameof(ImmutableObjectGraph.Optional <int> .GetValueOrDefault))),
                SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(defaultValue)))));
 }
Ejemplo n.º 22
0
        private async Task <Document> AddBackingFieldAsync(Document document, SyntaxNode equalsSyntax, CancellationToken cancellationToken)
        {
            var pds = equalsSyntax as PropertyDeclarationSyntax;

            var propName = pds.Identifier.ToString();

            var fieldName = "_" + char.ToLowerInvariant(propName[0]) + propName.Substring(1);

            var fieldType = pds.GetTypeName();

            var backingField = SyntaxFactory.FieldDeclaration(
                SyntaxFactory.VariableDeclaration(
                    SyntaxFactory.ParseTypeName(fieldType),
                    SyntaxFactory.SeparatedList(
                        new[]
            {
                SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(fieldName)),
            })))
                               .AddModifiers(SyntaxFactory.Token(SyntaxKind.PrivateKeyword));

            PropertyDeclarationSyntax newProperty =
                SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName(fieldType), propName)
                .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword));

            newProperty = newProperty.AddAccessorListAccessors(
                SyntaxFactory.AccessorDeclaration(
                    SyntaxKind.GetAccessorDeclaration,
                    SyntaxFactory.Block(
                        SyntaxFactory.List(new[]
            {
                SyntaxFactory.ReturnStatement(SyntaxFactory.IdentifierName(fieldName)),
            }))));

            var setProperty = SyntaxFactory.ExpressionStatement(
                SyntaxFactory.AssignmentExpression(
                    SyntaxKind.SimpleAssignmentExpression,
                    SyntaxFactory.IdentifierName(fieldName),
                    SyntaxFactory.IdentifierName("value")),
                SyntaxFactory.Token(SyntaxKind.SemicolonToken));

            var onPropertyChangedCall = SyntaxFactory.ExpressionStatement(
                SyntaxFactory.InvocationExpression(
                    SyntaxFactory.IdentifierName("OnPropertyChanged"))
                .AddArgumentListArguments(
                    SyntaxFactory.Argument(
                        SyntaxFactory.InvocationExpression(
                            SyntaxFactory.IdentifierName("nameof"))
                        .AddArgumentListArguments(
                            SyntaxFactory.Argument(
                                SyntaxFactory.IdentifierName(propName))))));

            newProperty = newProperty.AddAccessorListAccessors(
                SyntaxFactory.AccessorDeclaration(
                    SyntaxKind.SetAccessorDeclaration,
                    SyntaxFactory.Block(SyntaxFactory.List(new[]
            {
                setProperty,
                onPropertyChangedCall,
            }))));

            var oldRoot = await document.GetSyntaxRootAsync(cancellationToken);

            var newNodes = new List <SyntaxNode>
            {
                backingField,
                newProperty,
            };

            var newRoot = oldRoot.ReplaceNode(pds, newNodes);

            return(document.WithSyntaxRoot(newRoot));
        }
Ejemplo n.º 23
0
        static async Task <Document> UseContainsCheckAsync(Document document, InvocationExpressionSyntax invocation, string replacementMethod, CancellationToken cancellationToken)
        {
            var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);

            var memberAccess = (MemberAccessExpressionSyntax)invocation.Expression;
            var invocationExpressionSyntax = (InvocationExpressionSyntax)invocation.ArgumentList.Arguments[0].Expression;

            var anyMethodInvocation = (MemberAccessExpressionSyntax)invocationExpressionSyntax.Expression;
            var anyTarget           = anyMethodInvocation.Expression;

            editor.ReplaceNode(
                invocation,
                invocation.WithArgumentList(
                    SyntaxFactory.ArgumentList(
                        SyntaxFactory.SeparatedList(invocationExpressionSyntax.ArgumentList.Arguments.Insert(0, SyntaxFactory.Argument(anyTarget)))))
                .WithExpression(memberAccess.WithName(SyntaxFactory.IdentifierName(replacementMethod))));

            return(editor.GetChangedDocument());
        }
Ejemplo n.º 24
0
        private async Task <Document> ConvertToDependencyPropertyAsync(Document document, PropertyDeclarationSyntax autoProperty, ClassDeclarationSyntax cls, CancellationToken cancellationToken)
        {
            var type                    = autoProperty.Type.ToString();
            var propName                = autoProperty.Identifier.Text;
            var propNameProperty        = $"{propName}Property";
            var propNamePropertyChanged = $"On{propName}PropertyChanged";
            var clsName                 = cls.Identifier.ToString();
            var defaultValue            = autoProperty.Initializer != null?autoProperty.Initializer.Value.ToString() : "null";

            // http://roslynquoter.azurewebsites.net/

            var members = new MemberDeclarationSyntax[] {
                SyntaxFactory.PropertyDeclaration(
                    SyntaxFactory.IdentifierName(type),
                    SyntaxFactory.Identifier(propName))
                .WithModifiers(
                    SyntaxFactory.TokenList(
                        SyntaxFactory.Token(
                            SyntaxKind.PublicKeyword)))
                .WithAccessorList(
                    SyntaxFactory.AccessorList(
                        SyntaxFactory.List <AccessorDeclarationSyntax>(
                            new AccessorDeclarationSyntax[] {
                    SyntaxFactory.AccessorDeclaration(
                        SyntaxKind.GetAccessorDeclaration,
                        SyntaxFactory.Block(
                            SyntaxFactory.SingletonList <StatementSyntax>(
                                SyntaxFactory.ReturnStatement(
                                    SyntaxFactory.CastExpression(
                                        SyntaxFactory.IdentifierName(type),
                                        SyntaxFactory.InvocationExpression(
                                            SyntaxFactory.IdentifierName(
                                                @"GetValue"))
                                        .WithArgumentList(
                                            SyntaxFactory.ArgumentList(
                                                SyntaxFactory.SingletonSeparatedList <ArgumentSyntax>(
                                                    SyntaxFactory.Argument(
                                                        SyntaxFactory.IdentifierName(propNameProperty))))
                                            .WithOpenParenToken(
                                                SyntaxFactory.Token(
                                                    SyntaxKind.OpenParenToken))
                                            .WithCloseParenToken(
                                                SyntaxFactory.Token(
                                                    SyntaxKind.CloseParenToken))))
                                    .WithOpenParenToken(
                                        SyntaxFactory.Token(
                                            SyntaxKind.OpenParenToken))
                                    .WithCloseParenToken(
                                        SyntaxFactory.Token(
                                            SyntaxKind.CloseParenToken)))
                                .WithReturnKeyword(
                                    SyntaxFactory.Token(
                                        SyntaxKind.ReturnKeyword))
                                .WithSemicolonToken(
                                    SyntaxFactory.Token(
                                        SyntaxKind.SemicolonToken))))
                        .WithOpenBraceToken(
                            SyntaxFactory.Token(
                                SyntaxKind.OpenBraceToken))
                        .WithCloseBraceToken(
                            SyntaxFactory.Token(
                                SyntaxKind.CloseBraceToken)))
                    .WithKeyword(
                        SyntaxFactory.Token(
                            SyntaxKind.GetKeyword)),
                    SyntaxFactory.AccessorDeclaration(
                        SyntaxKind.SetAccessorDeclaration,
                        SyntaxFactory.Block(
                            SyntaxFactory.SingletonList <StatementSyntax>(
                                SyntaxFactory.ExpressionStatement(
                                    SyntaxFactory.InvocationExpression(
                                        SyntaxFactory.IdentifierName(
                                            @"SetValue"))
                                    .WithArgumentList(
                                        SyntaxFactory.ArgumentList(
                                            SyntaxFactory.SeparatedList <ArgumentSyntax>(
                                                new SyntaxNodeOrToken[] {
                        SyntaxFactory.Argument(
                            SyntaxFactory.IdentifierName(propNameProperty)),
                        SyntaxFactory.Token(
                            SyntaxKind.CommaToken),
                        SyntaxFactory.Argument(
                            SyntaxFactory.IdentifierName(
                                @"value"))
                    }))
                                        .WithOpenParenToken(
                                            SyntaxFactory.Token(
                                                SyntaxKind.OpenParenToken))
                                        .WithCloseParenToken(
                                            SyntaxFactory.Token(
                                                SyntaxKind.CloseParenToken))))
                                .WithSemicolonToken(
                                    SyntaxFactory.Token(
                                        SyntaxKind.SemicolonToken))))
                        .WithOpenBraceToken(
                            SyntaxFactory.Token(
                                SyntaxKind.OpenBraceToken))
                        .WithCloseBraceToken(
                            SyntaxFactory.Token(
                                SyntaxKind.CloseBraceToken)))
                    .WithKeyword(
                        SyntaxFactory.Token(
                            SyntaxKind.SetKeyword))
                }))
                    .WithOpenBraceToken(
                        SyntaxFactory.Token(
                            SyntaxKind.OpenBraceToken))
                    .WithCloseBraceToken(
                        SyntaxFactory.Token(
                            SyntaxKind.CloseBraceToken))),
                SyntaxFactory.FieldDeclaration(
                    SyntaxFactory.VariableDeclaration(
                        SyntaxFactory.IdentifierName(
                            @"DependencyProperty"))
                    .WithVariables(
                        SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                            SyntaxFactory.VariableDeclarator(
                                SyntaxFactory.Identifier(propNameProperty))
                            .WithInitializer(
                                SyntaxFactory.EqualsValueClause(
                                    SyntaxFactory.InvocationExpression(
                                        SyntaxFactory.MemberAccessExpression(
                                            SyntaxKind.SimpleMemberAccessExpression,
                                            SyntaxFactory.IdentifierName(
                                                @"DependencyProperty"),
                                            SyntaxFactory.IdentifierName(
                                                @"Register"))
                                        .WithOperatorToken(
                                            SyntaxFactory.Token(
                                                SyntaxKind.DotToken)))
                                    .WithArgumentList(
                                        SyntaxFactory.ArgumentList(
                                            SyntaxFactory.SeparatedList <ArgumentSyntax>(
                                                new SyntaxNodeOrToken[] {
                    SyntaxFactory.Argument(
                        SyntaxFactory.InvocationExpression(
                            SyntaxFactory.IdentifierName(
                                @"nameof"))
                        .WithArgumentList(
                            SyntaxFactory.ArgumentList(
                                SyntaxFactory.SingletonSeparatedList <ArgumentSyntax>(
                                    SyntaxFactory.Argument(
                                        SyntaxFactory.IdentifierName(propName))))
                            .WithOpenParenToken(
                                SyntaxFactory.Token(
                                    SyntaxKind.OpenParenToken))
                            .WithCloseParenToken(
                                SyntaxFactory.Token(
                                    SyntaxKind.CloseParenToken)))),
                    SyntaxFactory.Token(
                        SyntaxKind.CommaToken),
                    SyntaxFactory.Argument(
                        SyntaxFactory.TypeOfExpression(
                            SyntaxFactory.IdentifierName(type))
                        .WithKeyword(
                            SyntaxFactory.Token(
                                SyntaxKind.TypeOfKeyword))
                        .WithOpenParenToken(
                            SyntaxFactory.Token(
                                SyntaxKind.OpenParenToken))
                        .WithCloseParenToken(
                            SyntaxFactory.Token(
                                SyntaxKind.CloseParenToken))),
                    SyntaxFactory.Token(
                        SyntaxKind.CommaToken),
                    SyntaxFactory.Argument(
                        SyntaxFactory.TypeOfExpression(
                            SyntaxFactory.IdentifierName(clsName))
                        .WithKeyword(
                            SyntaxFactory.Token(
                                SyntaxKind.TypeOfKeyword))
                        .WithOpenParenToken(
                            SyntaxFactory.Token(
                                SyntaxKind.OpenParenToken))
                        .WithCloseParenToken(
                            SyntaxFactory.Token(
                                SyntaxKind.CloseParenToken))),
                    SyntaxFactory.Token(
                        SyntaxKind.CommaToken),
                    SyntaxFactory.Argument(
                        SyntaxFactory.ObjectCreationExpression(
                            SyntaxFactory.IdentifierName(
                                @"PropertyMetadata"))
                        .WithNewKeyword(
                            SyntaxFactory.Token(
                                SyntaxKind.NewKeyword))
                        .WithArgumentList(
                            SyntaxFactory.ArgumentList(
                                SyntaxFactory.SeparatedList <ArgumentSyntax>(
                                    new SyntaxNodeOrToken[] {
                        SyntaxFactory.Argument(
                            autoProperty.Initializer == null
                                                                        ? SyntaxFactory.DefaultExpression(SyntaxFactory.IdentifierName(type)) as ExpressionSyntax
                                                                        : SyntaxFactory.LiteralExpression(
                                SyntaxKind.NumericLiteralExpression,
                                SyntaxFactory.Literal(
                                    SyntaxFactory.TriviaList(),
                                    autoProperty.Initializer.Value.ToString(),
                                    autoProperty.Initializer.Value.ToString(),
                                    SyntaxFactory.TriviaList()))),
                        SyntaxFactory.Token(
                            SyntaxKind.CommaToken),
                        SyntaxFactory.Argument(
                            SyntaxFactory.IdentifierName(propNamePropertyChanged))
                    }))
                            .WithOpenParenToken(
                                SyntaxFactory.Token(
                                    SyntaxKind.OpenParenToken))
                            .WithCloseParenToken(
                                SyntaxFactory.Token(
                                    SyntaxKind.CloseParenToken))))
                }))
                                        .WithOpenParenToken(
                                            SyntaxFactory.Token(
                                                SyntaxKind.OpenParenToken))
                                        .WithCloseParenToken(
                                            SyntaxFactory.Token(
                                                SyntaxKind.CloseParenToken))))
                                .WithEqualsToken(
                                    SyntaxFactory.Token(
                                        SyntaxKind.EqualsToken))))))
                .WithModifiers(
                    SyntaxFactory.TokenList(
                        new [] {
                    SyntaxFactory.Token(
                        SyntaxKind.PublicKeyword),
                    SyntaxFactory.Token(
                        SyntaxKind.StaticKeyword),
                    SyntaxFactory.Token(
                        SyntaxKind.ReadOnlyKeyword)
                }))
                .WithSemicolonToken(
                    SyntaxFactory.Token(
                        SyntaxKind.SemicolonToken)),
                SyntaxFactory.MethodDeclaration(
                    SyntaxFactory.PredefinedType(
                        SyntaxFactory.Token(
                            SyntaxKind.VoidKeyword)),
                    SyntaxFactory.Identifier(propNamePropertyChanged))
                .WithModifiers(
                    SyntaxFactory.TokenList(
                        new [] {
                    SyntaxFactory.Token(
                        SyntaxKind.PrivateKeyword),
                    SyntaxFactory.Token(
                        SyntaxKind.StaticKeyword)
                }))
                .WithParameterList(
                    SyntaxFactory.ParameterList(
                        SyntaxFactory.SeparatedList <ParameterSyntax>(
                            new SyntaxNodeOrToken[] {
                    SyntaxFactory.Parameter(
                        SyntaxFactory.Identifier(
                            @"d"))
                    .WithType(
                        SyntaxFactory.IdentifierName(
                            @"DependencyObject")),
                    SyntaxFactory.Token(
                        SyntaxKind.CommaToken),
                    SyntaxFactory.Parameter(
                        SyntaxFactory.Identifier(
                            @"e"))
                    .WithType(
                        SyntaxFactory.IdentifierName(
                            @"DependencyPropertyChangedEventArgs"))
                }))
                    .WithOpenParenToken(
                        SyntaxFactory.Token(
                            SyntaxKind.OpenParenToken))
                    .WithCloseParenToken(
                        SyntaxFactory.Token(
                            SyntaxKind.CloseParenToken)))
                .WithBody(
                    SyntaxFactory.Block(
                        SyntaxFactory.List <StatementSyntax>(
                            new StatementSyntax[] {
                    SyntaxFactory.LocalDeclarationStatement(
                        SyntaxFactory.VariableDeclaration(
                            SyntaxFactory.IdentifierName(
                                @"var"))
                        .WithVariables(
                            SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                SyntaxFactory.VariableDeclarator(
                                    SyntaxFactory.Identifier(
                                        @"source"))
                                .WithInitializer(
                                    SyntaxFactory.EqualsValueClause(
                                        SyntaxFactory.BinaryExpression(
                                            SyntaxKind.AsExpression,
                                            SyntaxFactory.IdentifierName(
                                                @"d"),
                                            SyntaxFactory.IdentifierName(clsName))
                                        .WithOperatorToken(
                                            SyntaxFactory.Token(
                                                SyntaxKind.AsKeyword)))
                                    .WithEqualsToken(
                                        SyntaxFactory.Token(
                                            SyntaxKind.EqualsToken))))))
                    .WithSemicolonToken(
                        SyntaxFactory.Token(
                            SyntaxKind.SemicolonToken)),
                    SyntaxFactory.IfStatement(
                        SyntaxFactory.BinaryExpression(
                            SyntaxKind.NotEqualsExpression,
                            SyntaxFactory.IdentifierName(
                                @"source"),
                            SyntaxFactory.LiteralExpression(
                                SyntaxKind.NullLiteralExpression)
                            .WithToken(
                                SyntaxFactory.Token(
                                    SyntaxKind.NullKeyword)))
                        .WithOperatorToken(
                            SyntaxFactory.Token(
                                SyntaxKind.ExclamationEqualsToken)),
                        SyntaxFactory.Block(
                            //SyntaxFactory.SingletonList<StatementSyntax>(
                            //    SyntaxFactory.Token(SyntaxKind.SingleLineCommentTrivia)),
                            SyntaxFactory.SingletonList <StatementSyntax>(
                                SyntaxFactory.LocalDeclarationStatement(
                                    SyntaxFactory.VariableDeclaration(
                                        SyntaxFactory.IdentifierName(
                                            @"var"))
                                    .WithVariables(
                                        SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                            SyntaxFactory.VariableDeclarator(
                                                SyntaxFactory.Identifier(
                                                    @"value"))
                                            .WithInitializer(
                                                SyntaxFactory.EqualsValueClause(
                                                    SyntaxFactory.CastExpression(
                                                        SyntaxFactory.IdentifierName(type),
                                                        SyntaxFactory.MemberAccessExpression(
                                                            SyntaxKind.SimpleMemberAccessExpression,
                                                            SyntaxFactory.IdentifierName(
                                                                @"e"),
                                                            SyntaxFactory.IdentifierName(
                                                                @"NewValue"))
                                                        .WithOperatorToken(
                                                            SyntaxFactory.Token(
                                                                SyntaxKind.DotToken)))
                                                    .WithOpenParenToken(
                                                        SyntaxFactory.Token(
                                                            SyntaxKind.OpenParenToken))
                                                    .WithCloseParenToken(
                                                        SyntaxFactory.Token(
                                                            SyntaxKind.CloseParenToken)))
                                                .WithEqualsToken(
                                                    SyntaxFactory.Token(
                                                        SyntaxKind.EqualsToken))))))
                                .WithSemicolonToken(
                                    SyntaxFactory.Token(
                                        SyntaxFactory.TriviaList(),
                                        SyntaxKind.SemicolonToken,
                                        SyntaxFactory.TriviaList(
                                            SyntaxFactory.Comment(
                                                @" // TODO: Handle new value."))))))
                        .WithOpenBraceToken(
                            SyntaxFactory.Token(
                                SyntaxKind.OpenBraceToken))
                        .WithCloseBraceToken(
                            SyntaxFactory.Token(
                                SyntaxKind.CloseBraceToken)))
                    .WithIfKeyword(
                        SyntaxFactory.Token(
                            SyntaxKind.IfKeyword))
                    .WithOpenParenToken(
                        SyntaxFactory.Token(
                            SyntaxKind.OpenParenToken))
                    .WithCloseParenToken(
                        SyntaxFactory.Token(
                            SyntaxKind.CloseParenToken))
                }))
                    .WithOpenBraceToken(
                        SyntaxFactory.Token(
                            SyntaxKind.OpenBraceToken))
                    .WithCloseBraceToken(
                        SyntaxFactory.Token(
                            SyntaxKind.CloseBraceToken)))
            };

            // Replace old with new
            var oldRoot = await document.GetSyntaxRootAsync(cancellationToken)
                          .ConfigureAwait(false);

            var newRoot = oldRoot.ReplaceNode(autoProperty, members);

            return(document.WithSyntaxRoot(newRoot));
        }
Ejemplo n.º 25
0
            private MemberDeclarationSyntax CreateToDerivedTypeMethod(MetaType derivedType)
            {
                var derivedTypeName = GetFullyQualifiedSymbolName(derivedType.TypeSymbol);
                var thatLocal       = SyntaxFactory.IdentifierName("that");
                var body            = new List <StatementSyntax>();

                // var that = this as DerivedType;
                body.Add(SyntaxFactory.LocalDeclarationStatement(
                             SyntaxFactory.VariableDeclaration(
                                 varType,
                                 SyntaxFactory.SingletonSeparatedList(
                                     SyntaxFactory.VariableDeclarator(thatLocal.Identifier)
                                     .WithInitializer(SyntaxFactory.EqualsValueClause(
                                                          SyntaxFactory.BinaryExpression(
                                                              SyntaxKind.AsExpression,
                                                              SyntaxFactory.ThisExpression(),
                                                              derivedTypeName)))))));

                // this.GetType()
                var thisDotGetType = SyntaxFactory.InvocationExpression(
                    SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ThisExpression(), SyntaxFactory.IdentifierName("GetType")),
                    SyntaxFactory.ArgumentList());

                // {0}.Equals(typeof(derivedType))
                var thisTypeIsEquivalentToDerivedType =
                    SyntaxFactory.InvocationExpression(
                        SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            thisDotGetType,
                            SyntaxFactory.IdentifierName(nameof(Type.Equals))),
                        SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(
                                                                                            SyntaxFactory.TypeOfExpression(derivedTypeName)))));

                var ifEquivalentTypeBlock = new List <StatementSyntax>();
                var fieldsBeyond          = derivedType.GetFieldsBeyond(this.generator.applyToMetaType);

                if (fieldsBeyond.Any())
                {
                    Func <MetaField, ExpressionSyntax> isUnchanged = v =>
                                                                     SyntaxFactory.ParenthesizedExpression(
                        v.IsRequired
                                ? // ({0} == that.{1})
                        SyntaxFactory.BinaryExpression(
                            SyntaxKind.EqualsExpression,
                            v.NameAsField,
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                thatLocal,
                                v.NameAsProperty))
                                : // (!{0}.IsDefined || {0}.Value == that.{1})
                        SyntaxFactory.BinaryExpression(
                            SyntaxKind.LogicalOrExpression,
                            SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, Syntax.OptionalIsDefined(v.NameAsField)),
                            SyntaxFactory.BinaryExpression(
                                SyntaxKind.EqualsExpression,
                                Syntax.OptionalValue(v.NameAsField),
                                SyntaxFactory.MemberAccessExpression(
                                    SyntaxKind.SimpleMemberAccessExpression,
                                    thatLocal,
                                    v.NameAsProperty))));
                    var noChangesExpression = fieldsBeyond.Select(isUnchanged).ChainBinaryExpressions(SyntaxKind.LogicalAndExpression);

                    ifEquivalentTypeBlock.Add(SyntaxFactory.IfStatement(
                                                  noChangesExpression,
                                                  SyntaxFactory.ReturnStatement(thatLocal)));
                }
                else
                {
                    ifEquivalentTypeBlock.Add(SyntaxFactory.ReturnStatement(thatLocal));
                }

                // if (that != null && this.GetType().IsEquivalentTo(typeof(derivedType))) { ... }
                body.Add(SyntaxFactory.IfStatement(
                             SyntaxFactory.BinaryExpression(
                                 SyntaxKind.LogicalAndExpression,
                                 SyntaxFactory.BinaryExpression(SyntaxKind.NotEqualsExpression, thatLocal, SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression)),
                                 thisTypeIsEquivalentToDerivedType),
                             SyntaxFactory.Block(ifEquivalentTypeBlock)));

                // return DerivedType.CreateWithIdentity(...)
                body.Add(SyntaxFactory.ReturnStatement(
                             SyntaxFactory.InvocationExpression(
                                 SyntaxFactory.MemberAccessExpression(
                                     SyntaxKind.SimpleMemberAccessExpression,
                                     derivedTypeName,
                                     CreateWithIdentityMethodName),
                                 this.generator.CreateArgumentList(this.generator.applyToMetaType.AllFields, asOptional: OptionalStyle.WhenNotRequired)
                                 .AddArguments(RequiredIdentityArgumentFromProperty)
                                 .AddArguments(this.generator.CreateArgumentList(fieldsBeyond, ArgSource.Argument).Arguments.ToArray()))));

                return(SyntaxFactory.MethodDeclaration(
                           derivedTypeName,
                           GetToTypeMethodName(derivedType.TypeSymbol.Name).Identifier)
                       .AddModifiers(
                           SyntaxFactory.Token(SyntaxKind.PublicKeyword),
                           SyntaxFactory.Token(SyntaxKind.VirtualKeyword))
                       .WithParameterList(this.generator.CreateParameterList(fieldsBeyond, ParameterStyle.OptionalOrRequired))
                       .WithBody(SyntaxFactory.Block(body)));
            }
Ejemplo n.º 26
0
        public static InvocationExpressionSyntax InvokeWithNamedArguments(string target, string methodName, params string[] parameterNames)
        {
            var arguments = parameterNames.Select(pn => SyntaxFactory.Argument(SyntaxFactory.IdentifierName(pn))).AsArgumentList();

            return(Invoke(target, methodName, arguments));
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Emits the control builder invocation.
        /// </summary>
        public string EmitInvokeControlBuilder(Type controlType, string virtualPath)
        {
            UseType(controlType);

            var builderName = "c" + CurrentControlIndex + "_builder";
            var untypedName = "c" + CurrentControlIndex + "_untyped";
            var name        = "c" + CurrentControlIndex;

            CurrentControlIndex++;

            CurrentStatements.Add(
                SyntaxFactory.LocalDeclarationStatement(
                    SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName("var")).WithVariables(
                        SyntaxFactory.VariableDeclarator(builderName).WithInitializer(
                            SyntaxFactory.EqualsValueClause(
                                SyntaxFactory.InvocationExpression(
                                    SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                         SyntaxFactory.IdentifierName(ControlBuilderFactoryParameterName),
                                                                         SyntaxFactory.IdentifierName(GetControlBuilderFunctionName)
                                                                         ),
                                    SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] {
                SyntaxFactory.Argument(EmitStringLiteral(virtualPath))
            }))
                                    )
                                )
                            )
                        )
                    )
                );
            CurrentStatements.Add(
                SyntaxFactory.LocalDeclarationStatement(
                    SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName("var")).WithVariables(
                        SyntaxFactory.VariableDeclarator(untypedName).WithInitializer(
                            SyntaxFactory.EqualsValueClause(
                                SyntaxFactory.InvocationExpression(
                                    SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                         SyntaxFactory.IdentifierName(builderName),
                                                                         SyntaxFactory.IdentifierName(BuildControlFunctionName)
                                                                         ),
                                    SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] {
                SyntaxFactory.Argument(SyntaxFactory.IdentifierName(ControlBuilderFactoryParameterName))
            }))
                                    )
                                )
                            )
                        )
                    )
                );
            CurrentStatements.Add(
                SyntaxFactory.LocalDeclarationStatement(
                    SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName("var")).WithVariables(
                        SyntaxFactory.VariableDeclarator(name).WithInitializer(
                            SyntaxFactory.EqualsValueClause(
                                SyntaxFactory.CastExpression(ParseTypeName(controlType),
                                                             SyntaxFactory.IdentifierName(untypedName)
                                                             )
                                )
                            )
                        )
                    )
                );

            return(name);
        }
Ejemplo n.º 28
0
        public static InvocationExpressionSyntax InvokeMethodOnSelf(string methodName, params string[] parameterNames)
        {
            var arguments = parameterNames.Select(pn => SyntaxFactory.Argument(SyntaxFactory.IdentifierName(pn)));

            return(InvokeMethodOnSelf(methodName, arguments));
        }
Ejemplo n.º 29
0
 public ExpressionSyntax CreateDotvvmPropertyIdentifier(DotvvmProperty property)
 {
     if (property is GroupedDotvvmProperty)
     {
         var    gprop = (GroupedDotvvmProperty)property;
         string fieldName;
         if (!cachedGroupedDotvvmProperties.TryGetValue(gprop, out fieldName))
         {
             fieldName = $"_staticCachedGroupProperty_{cachedGroupedDotvvmProperties.Count}";
             cachedGroupedDotvvmProperties.Add(gprop, fieldName);
             otherDeclarations.Add(SyntaxFactory.FieldDeclaration(
                                       SyntaxFactory.VariableDeclaration(ParseTypeName(typeof(DotvvmProperty)),
                                                                         SyntaxFactory.SingletonSeparatedList(
                                                                             SyntaxFactory.VariableDeclarator(fieldName)
                                                                             .WithInitializer(SyntaxFactory.EqualsValueClause(
                                                                                                  SyntaxFactory.InvocationExpression(
                                                                                                      SyntaxFactory.ParseName(gprop.PropertyGroup.DeclaringType.FullName + "." + gprop.PropertyGroup.DescriptorField.Name
                                                                                                                              + "." + nameof(DotvvmPropertyGroup.GetDotvvmProperty)),
                                                                                                      SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(
                                                                                                                                     SyntaxFactory.Argument(this.EmitStringLiteral(gprop.GroupMemberName))
                                                                                                                                     ))
                                                                                                      )
                                                                                                  ))
                                                                             )
                                                                         )
                                       ));
         }
         return(SyntaxFactory.ParseName(fieldName));
     }
     else
     {
         return(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                     ParseTypeName(property.DeclaringType),
                                                     SyntaxFactory.IdentifierName(property.Name + "Property")));
     }
 }
Ejemplo n.º 30
0
        public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
        {
            //1. 先处理查询类方法的lambda表达式内的实体成员访问
            if (queryMethodCtx.HasAny && queryMethodCtx.Current.InLambdaExpression) //t.Customer.Name
            {
                var identifier = FindIndentifierForMemberAccessExpression(node);
                if (identifier != null)
                {
                    var replacedIdentifier = queryMethodCtx.Current.ReplaceLambdaParameter(identifier);
                    if (replacedIdentifier != null)
                    {
                        var sb = StringBuilderCache.Acquire();
                        BuildQueryMethodMemberAccess(node, replacedIdentifier, sb);
                        //TODO:判断是否由上级处理换行
                        //return SyntaxFactory.ParseExpression(sb.ToString()).WithTrailingTrivia(GetEndOfLineTrivia(node, false));
                        return(SyntaxFactory.ParseExpression(StringBuilderCache.GetStringAndRelease(sb)).WithTriviaFrom(node));
                    }
                }
            }
            else if (cqlFilterLambdaParameter != null)
            {
                if (node.Expression is IdentifierNameSyntax identifier &&
                    identifier.Identifier.ValueText == cqlFilterLambdaParameter)
                {
                    var sb = StringBuilderCache.Acquire();
                    CqlLambdaHelper.BuildCqlLambdaGetValue(sb, cqlFilterLambdaParameter,
                                                           -1, node.Name.Identifier.ValueText, node, SemanticModel);
                    return(SyntaxFactory.ParseExpression(StringBuilderCache.GetStringAndRelease(sb)));
                }
            }

            var expSymbol = SemanticModel.GetSymbolInfo(node).Symbol;
            //2. 判断有无拦截器
            var interceptor = GetMemberAccessInterceptor(expSymbol);

            if (interceptor != null)
            {
                return(interceptor.VisitMemberAccess(node, expSymbol, this));
            }

            //3. 正常处理成员访问
            if (expSymbol != null)
            {
                //先处理存储类的属性或方法
                var storeClass = TypeHelper.IsDataStoreClass(expSymbol.ContainingType);
                if (storeClass != null)
                {
                    //根据DataStore名称找到相应的节点
                    var storeName  = ((MemberAccessExpressionSyntax)node.Expression).Name;
                    var storeNode  = hub.DesignTree.FindDataStoreNodeByName(storeName.ToString());
                    var updateNode = SyntaxFactory.ParseExpression(string.Format("appbox.Store.{0}.Get({1}ul).{2}",
                                                                                 storeClass, storeNode.Model.Id, node.Name));
                    return(updateNode.WithTriviaFrom(node));
                }

                if (expSymbol.IsStatic && expSymbol is IMethodSymbol) //方法名称处理
                {
                    //处理需要转换类型的静态方法访问
                    var realTypeName = TypeHelper.GetRealTypeName(expSymbol.ContainingType);
                    if (!string.IsNullOrEmpty(realTypeName))
                    {
                        return(SyntaxFactory.ParseExpression($"{realTypeName}.{node.Name.Identifier.ValueText}"));
                    }
                }
                else //非方法名称处理
                {
                    if (TypeHelper.IsEntityClass(expSymbol.ContainingType)) //处理实体成员访问
                    {
                        //先处理TypeId静态成员(TODO:改用拦截器处理)
                        if (node.Name.Identifier.ValueText == "TypeId")
                        {
                            var names           = expSymbol.ContainingType.ToString().Split('.');
                            var appNode         = hub.DesignTree.FindApplicationNodeByName(names[0]);
                            var entityModelNode = hub.DesignTree.FindModelNodeByName(appNode.Model.Id, ModelType.Entity, names[2]);
                            return(SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression,
                                                                   SyntaxFactory.Literal(entityModelNode.Model.Id)));
                        }

                        //判断成员是否属于实体成员
                        if (!expSymbol.ContainingType.ToString().In(
                                new string[] { TypeHelper.Type_EntityBase, TypeHelper.Type_SysEntityBase,
                                               TypeHelper.Type_SqlEntityBase, TypeHelper.Type_CqlEntityBase }))
                        {
                            //TODO:判断是否AggregationRefField,返回的object类型,应使用BoxedValue处理
                            ITypeSymbol valueTypeSymbol = TypeHelper.GetSymbolType(expSymbol);
                            var         memberId        = GetEntityMemberId(expSymbol);

                            var oldTarget = (ExpressionSyntax)Visit(node.Expression);
                            //TODO: cache methodName
                            var methodName     = (SimpleNameSyntax)SyntaxFactory.ParseName(TypeHelper.GenEntityMemberGetterOrSetter(valueTypeSymbol, true));
                            var getValueMethod = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, oldTarget, methodName);
                            var arg1           = SyntaxFactory.Argument(SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression,
                                                                                                        SyntaxFactory.Literal(memberId)));
                            var argList = SyntaxFactory.ArgumentList().AddArguments(arg1);
                            return(SyntaxFactory.InvocationExpression(getValueMethod, argList));
                        }
                    }
                    else if (TypeHelper.IsEnumModel(expSymbol.ContainingType)) //处理枚举成员访问
                    {
                        throw ExceptionHelper.NotImplemented();
                        //var names = expSymbol.ContainingType.ToString().Split('.');
                        //var enumModel = DesignHelper.DesignTimeModelContainer.GetEnumModel(names[0] + "." + names[2]);
                        //int enumValue = 0;
                        //for (int i = 0; i < enumModel.Items.Count; i++)
                        //{
                        //    if (enumModel.Items[i].Name == node.Name.Identifier.ValueText)
                        //    {
                        //        enumValue = enumModel.Items[i].Value;
                        //    }
                        //}
                        //return SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression,
                        //SyntaxFactory.Literal(enumValue));
                    }
                    else if (expSymbol.IsStatic && (expSymbol is IPropertySymbol || expSymbol is IFieldSymbol))
                    {
                        //处理需要转换为运行时类型的静态成员访问, eg: PersistentState.Detached
                        var realTypeName = TypeHelper.GetRealTypeName(expSymbol.ContainingType);
                        if (!string.IsNullOrEmpty(realTypeName))
                        {
                            return(SyntaxFactory.ParseExpression($"{realTypeName}.{node.Name.Identifier.ValueText}"));
                        }
                    }
                }
            }

            return(base.VisitMemberAccessExpression(node));
        }