示例#1
0
 private string?GetAnsiConsoleParameterDeclaration()
 {
     return(_originalInvocation
            .Ancestors().OfType <MethodDeclarationSyntax>()
            .First()
            .ParameterList.Parameters
            .FirstOrDefault(i => i.Type.NormalizeWhitespace().ToString() == "IAnsiConsole")
            ?.Identifier.Text);
 }
        public override void VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            var symbol = (IMethodSymbol)SemanticModel.GetSymbolInfo(node).Symbol;

            if (symbol != null)
            {
                if(symbol.ToString().Contains("System.Threading.Tasks.Task.WaitAll"))
                {
                    var block = node.Ancestors().OfType<BlockSyntax>().First();

                    if (block.DescendantNodes().OfType<ForEachStatementSyntax>().Any() || block.DescendantNodes().OfType<ForStatementSyntax>().Any())
                        return;
                    foreach (var invocation in block.DescendantNodes().OfType<InvocationExpressionSyntax>())
                    {
                        var symbol2 = (IMethodSymbol)SemanticModel.GetSymbolInfo(invocation).Symbol;
                        if (symbol2!=null && symbol2.IsTaskCreationMethod())
                        {
                            Logs.TempLog3.Info("{0}{1}--------------------------", Document.FilePath, block.ToLog());
                            break;
                        }
                    }
                    
                }

            }


            base.VisitInvocationExpression(node);
        }
示例#3
0
        public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            // Replace the module method name with a qualified one if this is a module ctor
            bool nodeChanged = IsInvocationAModuleCtor(node);
            ExpressionSyntax nodeExpression = nodeChanged
                ? ((IdentifierNameSyntax)node.Expression).WithIdentifier(
                    SyntaxFactory.Identifier("ConfigScript." + ((IdentifierNameSyntax)node.Expression).Identifier.Text)
                        .WithTriviaFrom(((IdentifierNameSyntax)node.Expression).Identifier))
                : node.Expression;

            // Get a hash of all the previous @doc and @ctx lambda parameters and don't replace the same
            HashSet<string> currentScopeLambdaParameters = new HashSet<string>(
                node.Ancestors().OfType<LambdaExpressionSyntax>().SelectMany(
                    x => x.DescendantNodes().OfType<ParameterSyntax>()).Select(x => x.Identifier.Text));

            // Only do the replacement if this is a module ctor or a module fluent method
            ArgumentListSyntax argumentList = node.ArgumentList;
            if(nodeChanged || IsInvocationAFluentMethod(node))
            {
                // Replace @doc and @ctx argument expressions with the appropriate lambda expressions, and stop descending if we hit another module ctor
                foreach (ArgumentSyntax argument in node.ArgumentList.Arguments)
                {
                    // Don't replace existing lambda expressions
                    if (!(argument.Expression is LambdaExpressionSyntax))
                    {
                        List<IdentifierNameSyntax> identifierNames = argument
                            .DescendantNodes(x => !(x is InvocationExpressionSyntax) || !IsInvocationAModuleCtorOrFluentMethod((InvocationExpressionSyntax)x))
                            .OfType<IdentifierNameSyntax>()
                            .Where(x => x != null && !currentScopeLambdaParameters.Contains(x.Identifier.Text))
                            .ToList();
                        IdentifierNameSyntax docReplacementName = identifierNames.FirstOrDefault(x => x.Identifier.Text.StartsWith("@doc"));
                        IdentifierNameSyntax ctxReplacementName = identifierNames.FirstOrDefault(x => x.Identifier.Text.StartsWith("@ctx"));
                        if (docReplacementName != null)
                        {
                            argumentList = argumentList.ReplaceNode(argument, SyntaxFactory.Argument(
                                SyntaxFactory.ParenthesizedLambdaExpression(
                                    SyntaxFactory.ParameterList(
                                        new SeparatedSyntaxList<ParameterSyntax>()
                                            .Add(SyntaxFactory.Parameter(SyntaxFactory.Identifier(docReplacementName.Identifier.Text)))
                                            .Add(SyntaxFactory.Parameter(SyntaxFactory.Identifier(ctxReplacementName == null ? "_" : ctxReplacementName.Identifier.Text)))),
                                    argument.Expression))
                                .WithTriviaFrom(argument));
                            nodeChanged = true;
                        }
                        else if (ctxReplacementName != null)
                        {
                            argumentList = argumentList.ReplaceNode(argument, SyntaxFactory.Argument(
                                SyntaxFactory.SimpleLambdaExpression(
                                    SyntaxFactory.Parameter(SyntaxFactory.Identifier(ctxReplacementName.Identifier.Text)),
                                    argument.Expression))
                                .WithTriviaFrom(argument));
                            nodeChanged = true;
                        }
                    }
                }
            }

            // Build and return the result node (or just return the original node)
            return base.VisitInvocationExpression(nodeChanged ? node.WithExpression(nodeExpression).WithArgumentList(argumentList) : node);
        }
        private static bool IsInsideANullCheck(InvocationExpressionSyntax invocation, SemanticModel semanticModel, ISymbol symbol)
        {
            var ifs = invocation.Ancestors().OfType <IfStatementSyntax>();

            foreach (IfStatementSyntax @if in ifs)
            {
                if ([email protected]?.IsKind(SyntaxKind.NotEqualsExpression) ?? true)
                {
                    continue;
                }
                var equals = (BinaryExpressionSyntax)@if.Condition;
                if (equals.Left == null || equals.Right == null)
                {
                    continue;
                }
                ISymbol identifierSymbol;
                if (equals.Right.IsKind(SyntaxKind.NullLiteralExpression) && equals.Left.IsKind(SyntaxKind.IdentifierName))
                {
                    identifierSymbol = semanticModel.GetSymbolInfo(equals.Left).Symbol;
                }
                else if (equals.Left.IsKind(SyntaxKind.NullLiteralExpression) && equals.Right.IsKind(SyntaxKind.IdentifierName))
                {
                    identifierSymbol = semanticModel.GetSymbolInfo(equals.Right).Symbol;
                }
                else
                {
                    continue;
                }
                if (symbol.Equals(identifierSymbol))
                {
                    return(true);
                }
            }
            return(false);
        }
        public override void VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            try
            {
                var target = _semanticModel.GetSymbolInfo(node.Expression);

                if (target.Symbol.Name == "SetCommandType")
                {
                    var commandTypeParameter = node.ArgumentList.Arguments[1].Expression as MemberAccessExpressionSyntax;
                    if (commandTypeParameter != null && commandTypeParameter.Name.Identifier.ValueText == "StoredProcedure")
                    {
                        var storedProcedureName = _semanticModel.GetConstantValue(node.ArgumentList.Arguments[2].Expression).Value.ToString();
                        var parent = node.Ancestors().First(x => x is MethodDeclarationSyntax);
                        var source = _semanticModel.GetDeclaredSymbol(parent);

                        CreateMethodInvokesStoredProcedureRelationship(source, storedProcedureName);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception: " + ex);
            }

            base.VisitInvocationExpression(node);
        }
        public override void VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            IEnumerable <IdentifierNameSyntax> objectAndMethod = node.Expression.DescendantNodes()
                                                                 .OfType <IdentifierNameSyntax>()
                                                                 .TakeLast(2);

            if (objectAndMethod.Count() == 2)
            {
                // Assumption: for this analyser, assuming that variables are declared with a type (not var/base class/interface)
                IdentifierNameSyntax classIdentifier = objectAndMethod.First();
                SyntaxNode           declaration     = IdentifierDeclarationFinder.Find(classIdentifier);
                string className = declaration != null
                    ? declaration.ChildNodes().OfType <VariableDeclarationSyntax>().FirstOrDefault()?.Type.ToString()
                                   // no declaration was found, assume static method
                    : classIdentifier.Identifier.Text;

                MethodCalls.Add(new MethodCallHolder(className, node));
            }
            else
            {
                string className = node.Ancestors()
                                   .OfType <ClassDeclarationSyntax>()
                                   .FirstOrDefault()?
                                   .Identifier
                                   .Text;

                MethodCalls.Add(new MethodCallHolder(className, node));
            }

            base.VisitInvocationExpression(node);
        }
            public override void VisitInvocationExpression(InvocationExpressionSyntax node)
            {
                var invokedSymbol = semanticModel.GetSymbolInfo(node).Symbol as IMethodSymbol;

                if (invokedSymbol == null)
                {
                    return;
                }

                if (!invokedSymbol.IsArrayClone() &&
                    !invokedSymbol.IsEnumerableToList() &&
                    !invokedSymbol.IsEnumerableToArray())
                {
                    return;
                }

                var returnOrAssignment = node
                                         .Ancestors()
                                         .FirstOrDefault(IsReturnOrAssignment);

                if (IsReturn(returnOrAssignment))
                {
                    locations.Add(node.Expression.GetLocation());
                }
            }
示例#8
0
        protected virtual async Task <bool> IsRegistrableAsync(CodeFixContext context, InvocationExpressionSyntax invocation)
        {
            // for now we do not offer codefixes for mixed types
            var model = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

            if (!(invocation.Expression is MemberAccessExpressionSyntax maes))
            {
                return(true);
            }

            if (!(model.GetTypeInfo(maes.ChildNodes().FirstOrDefault()).Type is INamedTypeSymbol typeInvocationContext))
            {
                return(false);
            }

            var mdec = invocation
                       .Ancestors()
                       .OfType <MethodDeclarationSyntax>()
                       .FirstOrDefault();

            if (mdec == null)
            {
                return(false);
            }

            var symbol      = model.GetDeclaredSymbol(mdec);
            var typeContext = symbol?.ContainingType;

            return(typeContext != null && SymbolEqualityComparer.Default.Equals(typeContext, typeInvocationContext));
        }
示例#9
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, InvocationExpressionSyntax invocation)
        {
            if (CheckSpan(invocation, context.Span))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                IMethodSymbol methodSymbol = GetMethodSymbol(invocation, semanticModel, context.CancellationToken);

                if (methodSymbol != null)
                {
                    MethodDeclarationSyntax method = await GetMethodAsync(methodSymbol, context.CancellationToken).ConfigureAwait(false);

                    if (method != null &&
                        !invocation.Ancestors().Any(f => f == method))
                    {
                        ExpressionSyntax expression = GetMethodExpression(method);

                        if (expression != null)
                        {
                            List <ParameterInfo> parameterInfos = GetParameterInfos(invocation, methodSymbol, semanticModel, context.CancellationToken);

                            if (parameterInfos != null)
                            {
                                context.RegisterRefactoring(
                                    "Inline method",
                                    c => InlineMethodAsync(context.Document, invocation, expression, parameterInfos.ToArray(), c));

                                context.RegisterRefactoring(
                                    "Inline and remove method",
                                    c => InlineAndRemoveMethodAsync(context.Document, invocation, method, expression, parameterInfos.ToArray(), c));
                            }
                        }
                        else if (methodSymbol.ReturnsVoid &&
                                 invocation.IsParentKind(SyntaxKind.ExpressionStatement))
                        {
                            StatementSyntax[] statements = method.Body?.Statements.ToArray();

                            if (statements?.Length > 0)
                            {
                                List <ParameterInfo> parameterInfos = GetParameterInfos(invocation, methodSymbol, semanticModel, context.CancellationToken);

                                if (parameterInfos != null)
                                {
                                    var expressionStatement = (ExpressionStatementSyntax)invocation.Parent;

                                    context.RegisterRefactoring(
                                        "Inline method",
                                        c => InlineMethodAsync(context.Document, expressionStatement, statements, parameterInfos.ToArray(), c));

                                    context.RegisterRefactoring(
                                        "Inline and remove method",
                                        c => InlineAndRemoveMethodAsync(context.Document, expressionStatement, method, statements, parameterInfos.ToArray(), c));
                                }
                            }
                        }
                    }
                }
            }
        }
        public override void VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            var symbol = (IMethodSymbol)SemanticModel.GetSymbolInfo(node).Symbol;

            if (symbol != null)
            {
                var synctype = DetectSynchronousUsages((IMethodSymbol)symbol.OriginalDefinition);
                Result.StoreDetectedSyncUsage(synctype);
                Result.WriteDetectedSyncUsage(synctype, Document.FilePath, (IMethodSymbol)symbol.OriginalDefinition);
                if (synctype != Utilities.Enums.SyncDetected.None
                        && node.Ancestors().OfType<MethodDeclarationSyntax>().Any(method => method.HasAsyncModifier()))
                {
                    Result.syncUsageResults.NumGUIBlockingSyncUsages++;
                    Logs.TempLog.Info(@"GUIBLOCKING {0}", node.Ancestors().OfType<MethodDeclarationSyntax>().First().ToString());
                }
            }
        }
示例#11
0
 protected override bool IsInValidContext(InvocationExpressionSyntax invocationSyntax,
                                          SemanticModel semanticModel) =>
 // Do not report if call is inside Main.
 !invocationSyntax
 .Ancestors()
 .OfType <BaseMethodDeclarationSyntax>()
 .Select(m => semanticModel.GetDeclaredSymbol(m))
 .Select(s => s.IsMainMethod())
 .FirstOrDefault();
        private static async Task <Document> AddCancellationTokenAsync(Document document, InvocationExpressionSyntax invocation, CancellationToken cancellationToken)
        {
            SyntaxNode?root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            if (root is null)
            {
                return(document);
            }

            if (invocation.Ancestors().OfType <MethodDeclarationSyntax>().FirstOrDefault() is { ParameterList : { Parameters : { } callerParameters } } &&
示例#13
0
        public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            // Get a hash of all the previous @doc and @ctx lambda parameters and don't replace the same
            HashSet <string> currentScopeLambdaParameters = new HashSet <string>(
                node.Ancestors().OfType <LambdaExpressionSyntax>().SelectMany(
                    x => x.DescendantNodes().OfType <ParameterSyntax>()).Select(x => x.Identifier.Text));

            // Only do the replacement if this is a module ctor or a module fluent method
            ArgumentListSyntax argumentList = node.ArgumentList;
            bool nodeChanged = false;

            if (IsInvocationAModuleCtorOrFluentMethod(node))
            {
                // Replace @doc and @ctx argument expressions with the appropriate lambda expressions, and stop descending if we hit another module ctor
                foreach (ArgumentSyntax argument in node.ArgumentList.Arguments)
                {
                    // Don't replace existing lambda expressions
                    if (!(argument.Expression is LambdaExpressionSyntax))
                    {
                        List <IdentifierNameSyntax> identifierNames = argument
                                                                      .DescendantNodes(x => !(x is InvocationExpressionSyntax) || !IsInvocationAModuleCtorOrFluentMethod((InvocationExpressionSyntax)x))
                                                                      .OfType <IdentifierNameSyntax>()
                                                                      .Where(x => x != null && !currentScopeLambdaParameters.Contains(x.Identifier.Text))
                                                                      .ToList();
                        IdentifierNameSyntax docReplacementName = identifierNames.FirstOrDefault(x => x.Identifier.Text.StartsWith("@doc"));
                        IdentifierNameSyntax ctxReplacementName = identifierNames.FirstOrDefault(x => x.Identifier.Text.StartsWith("@ctx"));
                        if (docReplacementName != null)
                        {
                            argumentList = argumentList.ReplaceNode(argument, SyntaxFactory.Argument(
                                                                        SyntaxFactory.ParenthesizedLambdaExpression(
                                                                            SyntaxFactory.ParameterList(
                                                                                default(SeparatedSyntaxList <ParameterSyntax>)
                                                                                .Add(SyntaxFactory.Parameter(SyntaxFactory.Identifier(docReplacementName.Identifier.Text)))
                                                                                .Add(SyntaxFactory.Parameter(SyntaxFactory.Identifier(ctxReplacementName == null ? "_" : ctxReplacementName.Identifier.Text)))),
                                                                            argument.Expression))
                                                                    .WithTriviaFrom(argument));
                            nodeChanged = true;
                        }
                        else if (ctxReplacementName != null)
                        {
                            argumentList = argumentList.ReplaceNode(argument, SyntaxFactory.Argument(
                                                                        SyntaxFactory.SimpleLambdaExpression(
                                                                            SyntaxFactory.Parameter(SyntaxFactory.Identifier(ctxReplacementName.Identifier.Text)),
                                                                            argument.Expression))
                                                                    .WithTriviaFrom(argument));
                            nodeChanged = true;
                        }
                    }
                }
            }

            // Build and return the result node (or just return the original node)
            return(base.VisitInvocationExpression(nodeChanged ? node.WithArgumentList(argumentList) : node));
        }
示例#14
0
        public static object ResolveFunctionInvocation(string functionName, InvocationExpressionSyntax node, SemanticModel semanticModel)
        {
            var returnType     = "void";
            var varDeclaration = node.Ancestors().OfType <VariableDeclarationSyntax>().FirstOrDefault();

            if (varDeclaration != null)
            {
                var predefinedType = varDeclaration.ChildNodes().OfType <PredefinedTypeSyntax>().FirstOrDefault();
                returnType = predefinedType?.Keyword.Value.ToString() ?? "object";
            }
            var arguments = GetArgumentTypes(node.ArgumentList.Arguments, semanticModel);

            return(new FunctionDescription(functionName, returnType, arguments));
        }
示例#15
0
        private void Initialize(int depth, InvocationExpressionSyntax invocationExpressionSyntax,
                                IMethodSymbol methodSymbol, SemanticModel semanticModel)
        {
            Depth            = depth;
            IsMethod         = true;
            InvocationString = invocationExpressionSyntax.ToString();
            var containingNode = invocationExpressionSyntax.Ancestors().OfType <StatementSyntax>().FirstOrDefault();

            OwnerStatementString = containingNode?.ToString();


            MemberName = methodSymbol.Name;
            ReturnType = new TypeDescriptor(methodSymbol.ReturnType);
            var containingTypeSymbol = methodSymbol.ContainingType;

            ContainingType = new TypeDescriptor(containingTypeSymbol);

            ParameterTypes = invocationExpressionSyntax.ArgumentList.Arguments
                             .Select(a => new TypeDescriptor(semanticModel.GetTypeInfo(a.Expression).Type))
                             .ToList();

            GenericTypesForMethod = methodSymbol.IsGenericMethod ? methodSymbol.TypeArguments
                                    .Select(t => new TypeDescriptor(t))
                                    .ToList() : null;

            GenericTypesForContainedType = containingTypeSymbol.IsGenericType ? containingTypeSymbol.TypeArguments
                                           .Select(t => new TypeDescriptor(t))
                                           .ToList() : null;

            MethodDeclarationSyntax = SymbolHelper.GetSyntaxReferences(invocationExpressionSyntax, semanticModel)
                                      .FirstOrDefault()
                                      ?.GetSyntax() as MethodDeclarationSyntax;

            if (invocationExpressionSyntax.Expression is MemberAccessExpressionSyntax memberAccessExpressionSyntax)
            {
                var memberAccessSymbolInfo = semanticModel.GetSymbolInfo(memberAccessExpressionSyntax);

                // info on the variable being accessed
                var objectAccessedSyntax     = memberAccessExpressionSyntax.Expression;
                var objectAccessedSymbol     = semanticModel.GetSymbolInfo(objectAccessedSyntax).Symbol;
                var objectAccessedTypeSymbol = semanticModel.GetTypeInfo(objectAccessedSyntax).Type;
                MemberOwnerType = new TypeDescriptor(objectAccessedTypeSymbol);
            }
            else
            {
                // a method that is part of the current class (containingType)
                MemberOwnerType = ContainingType;
            }
        }
示例#16
0
        private void AnalyzeCodeBlock(SyntaxNodeAnalysisContext context)
        {
            InvocationExpressionSyntax call = context.Node as InvocationExpressionSyntax;

            if (call == null)
            {
                return;
            }

            // If we are not calling the DefineSwitchDefault methods on LocalAppContext then we can safely ignore this.
            if (!IsCallToDefineSwitchDefault(call, context.SemanticModel))
            {
                return;
            }

            // Validate that the second argument is true.
            ArgumentSyntax args = call.ArgumentList.Arguments[1];

            if (args.Expression.Kind() != SyntaxKind.TrueLiteralExpression)
            {
                context.ReportDiagnostic(Diagnostic.Create(s_appContextDefaultNotInitializedToTrueDiagnostic, args.GetLocation(), call));
            }

            // check that we are doing this inside an if statement
            var containingIfStatement = call.Ancestors().FirstOrDefault(n => n.Kind() == SyntaxKind.IfStatement) as IfStatementSyntax;

            if (containingIfStatement == null)
            {
                context.ReportDiagnostic(Diagnostic.Create(s_appContextDefaultValueDefinedOutsideIfConditionDiagnostic, args.GetLocation(), call));
            }
            else
            {
                // are we inside the switch? either as a block or as a switchcase?
                if (!(containingIfStatement.Parent.Kind() == SyntaxKind.SwitchSection ||
                      containingIfStatement.Parent.Parent.Kind() == SyntaxKind.SwitchSection))
                {
                    context.ReportDiagnostic(Diagnostic.Create(s_appContextDefaultValueDefinedOutsideIfConditionDiagnostic, args.GetLocation(), call));
                }
            }

            // Validate that the if statement is using the appropriate expression
            if (containingIfStatement.Condition.Kind() != SyntaxKind.LessThanOrEqualExpression)
            {
                context.ReportDiagnostic(Diagnostic.Create(s_appContextDefaultUsedUnexpectedIfStatementDiagnostic, containingIfStatement.GetLocation()));
            }
        }
示例#17
0
        private bool isFunctionalCall(InvocationExpressionSyntax invocation, out StatementSyntax functional)
        {
            functional = null;
            var containingClass = invocation
                                  .Ancestors()
                                  .OfType <ClassDeclarationSyntax>()
                                  .FirstOrDefault();

            if (containingClass == null)
            {
                return(false);
            }

            var parentContainer = containingClass.Parent as ClassDeclarationSyntax;

            if (parentContainer == null || parentContainer.Identifier.ToString() != "Functions")
            {
                return(false);
            }

            var concurrentClassName = invocation.Expression.ToString() + "__concurrent";
            var concurrentClass     = parentContainer
                                      .Members
                                      .OfType <ClassDeclarationSyntax>()
                                      .SingleOrDefault(@class => @class.Identifier.ToString() == concurrentClassName);

            var newInvocation = default(InvocationExpressionSyntax);

            if (concurrentClass != null)
            {
                newInvocation = Templates.ConcurrentFunctionStatement
                                .Get <InvocationExpressionSyntax>(
                    concurrentClass.Identifier,
                    (invocation.Expression as IdentifierNameSyntax)
                    .Identifier);
            }
            else
            {
                newInvocation = Templates.FunctionStatement
                                .Get <InvocationExpressionSyntax>(invocation.Expression);
            }

            functional = CSharp.ExpressionStatement(newInvocation);
            return(true);
        }
 private ITypeSymbol GetClassOrStructContainingExpression(
     InvocationExpressionSyntax expr,
     SemanticModel semanticModel
     )
 {
     foreach (var ancestor in expr.Ancestors())
     {
         if (ancestor is StructDeclarationSyntax)
         {
             return(semanticModel.GetDeclaredSymbol(ancestor as StructDeclarationSyntax));
         }
         else if (ancestor is ClassDeclarationSyntax)
         {
             return(semanticModel.GetDeclaredSymbol(ancestor as ClassDeclarationSyntax));
         }
     }
     return(null);
 }
        public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            var expression = node.Expression.ToString();

            if (expression.EndsWith("OrderBy") == false)
            {
                return(base.VisitInvocationExpression(node));
            }

            var parent = node.Ancestors().FirstOrDefault(x => x.IsKind(SyntaxKind.InvocationExpression) || x.IsKind(SyntaxKind.QueryExpression));

            if (parent != _root)
            {
                return(base.VisitInvocationExpression(node));
            }

            ThrowOrderByException(node.ToString());
            return(node);
        }
示例#20
0
        static bool ValidateInvocation(InvocationExpressionSyntax expr)
        {
            bool allAncestorsIsParenthes = true;
            foreach (var x in expr.Ancestors())
            {
                // scope is in lambda, method
                if (x.IsKind(SyntaxKind.SimpleLambdaExpression) || x.IsKind(SyntaxKind.ParenthesizedLambdaExpression) || x.IsKind(SyntaxKind.ArrowExpressionClause))
                {
                    // () => M()
                    if (allAncestorsIsParenthes) return true;
                    break;
                }
                if (x.IsKind(SyntaxKind.MethodDeclaration)) break;
                if (x.IsKind(SyntaxKind.PropertyDeclaration)) break;
                if (x.IsKind(SyntaxKind.ConstructorDeclaration)) break;

                // x = M()
                if (x.IsKind(SyntaxKind.SimpleAssignmentExpression)) return true;
                // var x = M()
                if (x.IsKind(SyntaxKind.VariableDeclarator)) return true;
                // return M()
                if (x.IsKind(SyntaxKind.ReturnStatement)) return true;
                // from x in M()
                if (x.IsKind(SyntaxKind.FromClause)) return true;
                // (bool) ? M() : M()
                if (x.IsKind(SyntaxKind.ConditionalExpression)) return true;
                // M(M())
                if (x.IsKind(SyntaxKind.InvocationExpression)) return true;
                // new C(M())
                if (x.IsKind(SyntaxKind.ObjectCreationExpression)) return true;

                // (((((M()))))
                if (!x.IsKind(SyntaxKind.ParenthesizedExpression))
                {
                    allAncestorsIsParenthes = false;
                }
            }

            // Okay => M().M()
            if (expr.DescendantNodes().OfType<InvocationExpressionSyntax>().Any()) return true;

            return false;
        }
示例#21
0
            public (EarlyReleaseReason?Reason, IMethodSymbol EnclosingMethodSymbol, Location InvocationLocation, Location EnclosingMethodLocation) GetEarlyReleaseJustification([NotNull] Compilation comp,
                                                                                                                                                                                [NotNull] InvocationExpressionSyntax ies,
                                                                                                                                                                                CancellationToken token)
            {
                if (comp == null)
                {
                    throw new ArgumentNullException(nameof(comp));
                }
                if (ies == null)
                {
                    throw new ArgumentNullException(nameof(ies));
                }
                EarlyReleaseReason?ret = null;
                IMethodSymbol      enclosingMethodSym      = null;
                Location           invocationLocation      = ies.GetLocation();
                Location           enclosingMethodLocation = null;
                var semanticModel = comp.GetSemanticModel(ies.SyntaxTree, true);

                if (semanticModel != null)
                {
                    INamedTypeSymbol earlyReleaseJustificationAttrib = FindEarlyReleaseJustificationAttribute(comp);
                    var enclosingMethod = ies.Ancestors().OfType <MethodDeclarationSyntax>().FirstOrDefault();
                    if (enclosingMethod != null && earlyReleaseJustificationAttrib != null)
                    {
                        var symbolInfo = semanticModel.GetDeclaredSymbol(enclosingMethod, token);
                        if (symbolInfo is IMethodSymbol enclosingMethodSymbol)
                        {
                            enclosingMethodSym      = enclosingMethodSymbol;
                            enclosingMethodLocation = enclosingMethodSym.Locations.FirstOrDefault();
                            var justRes = ExtractJustification(enclosingMethodSymbol,
                                                               earlyReleaseJustificationAttrib, comp);
                            LogWhetherHasJustificationAttribute(justRes.HasAttribute,
                                                                enclosingMethodSymbol.Name ?? "UNKNOWN");
                            ret = justRes.PropertyValue;
                        }
                    }
                }
                Debug.Assert(!ret.HasValue || ret.Value.IsDefined());
                Debug.Assert(!ret.HasValue || (enclosingMethodSym != null && invocationLocation != null &&
                                               enclosingMethodLocation != null));
                return(ret, enclosingMethodSym, invocationLocation, enclosingMethodLocation);
            }
        public override void VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            try
            {
                var target = _semanticModel.GetSymbolInfo(node.Expression);

                var parent = node.Ancestors().First(x => x is ClassDeclarationSyntax || x is MethodDeclarationSyntax);
                if (parent is ClassDeclarationSyntax)
                {
                    //_semanticModel.GetDeclaredSymbol(parent);
                }
                else
                {
                    var source = _semanticModel.GetDeclaredSymbol(parent);
                    CreateMethodInvokesMethodRelationship(source, target.Symbol);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception: " + ex);
            }

            base.VisitInvocationExpression(node);
        }
示例#23
0
        static bool ValidateInvocation(InvocationExpressionSyntax expr)
        {
            bool allAncestorsIsParenthes = true;

            foreach (var x in expr.Ancestors())
            {
                // scope is in lambda, method
                if (x.IsKind(SyntaxKind.SimpleLambdaExpression) || x.IsKind(SyntaxKind.ParenthesizedLambdaExpression) || x.IsKind(SyntaxKind.ArrowExpressionClause))
                {
                    // () => M()
                    if (allAncestorsIsParenthes)
                    {
                        return(true);
                    }
                    break;
                }
                if (x.IsKind(SyntaxKind.MethodDeclaration))
                {
                    break;
                }
                if (x.IsKind(SyntaxKind.PropertyDeclaration))
                {
                    break;
                }
                if (x.IsKind(SyntaxKind.ConstructorDeclaration))
                {
                    break;
                }

                // x = M()
                if (x.IsKind(SyntaxKind.SimpleAssignmentExpression))
                {
                    return(true);
                }
                // var x = M()
                if (x.IsKind(SyntaxKind.VariableDeclarator))
                {
                    return(true);
                }
                // return M()
                if (x.IsKind(SyntaxKind.ReturnStatement))
                {
                    return(true);
                }
                // from x in M()
                if (x.IsKind(SyntaxKind.FromClause))
                {
                    return(true);
                }
                // (bool) ? M() : M()
                if (x.IsKind(SyntaxKind.ConditionalExpression))
                {
                    return(true);
                }
                // M(M())
                if (x.IsKind(SyntaxKind.InvocationExpression))
                {
                    return(true);
                }
                // new C(M())
                if (x.IsKind(SyntaxKind.ObjectCreationExpression))
                {
                    return(true);
                }

                // (((((M()))))
                if (!x.IsKind(SyntaxKind.ParenthesizedExpression))
                {
                    allAncestorsIsParenthes = false;
                }
            }

            // Okay => M().M()
            if (expr.DescendantNodes().OfType <InvocationExpressionSyntax>().Any())
            {
                return(true);
            }

            return(false);
        }
        private void APMDiagnosisDetection(IMethodSymbol symbol, InvocationExpressionSyntax node)
        {
            int c = GetIndexCallbackArgument(symbol);

            var callbackArg = node.ArgumentList.Arguments.ElementAt(c);

            if (callbackArg.Expression.CSharpKind().ToString().Contains("IdentifierName"))
                Logs.TempLog.Info("{0} {1}", callbackArg.Expression.CSharpKind(), SemanticModel.GetSymbolInfo(callbackArg.Expression).Symbol.Kind);
            else
                Logs.TempLog.Info("{0}", callbackArg.Expression.CSharpKind());
            
           
            //PRINT ALL APM BEGIN METHODS
            Logs.APMDiagnosisLog.Info(@"Document: {0}", Document.FilePath);
            Logs.APMDiagnosisLog.Info(@"Symbol: {0}", symbol);
            Logs.APMDiagnosisLog.Info(@"Invocation: {0}", node);
            Logs.APMDiagnosisLog.Info(@"CallbackType: {0}", callbackArg.Expression.CSharpKind());
            if (callbackArg.Expression.CSharpKind().ToString().Contains("IdentifierName"))
                Logs.APMDiagnosisLog.Info("{0}", SemanticModel.GetSymbolInfo(callbackArg.Expression).Symbol.Kind);
            Logs.APMDiagnosisLog.Info("---------------------------------------------------");

            Result.apmDiagnosisResults.NumAPMBeginMethods++;





            if (node.Ancestors().Where(a => (a is BinaryExpressionSyntax) || (a is VariableDeclaratorSyntax) || (a is VariableDeclarationSyntax) || (a is ReturnStatementSyntax)).Any() )
            {
                Logs.TempLog2.Info("UnderStatement {0}\r\n{1}\r\n--------------------", Document.FilePath, node.Ancestors().OfType<BlockSyntax>().First());
            }



            //var statement = node.Ancestors().OfType<StatementSyntax>().First();
            //var ancestors = node.Ancestors().OfType<MethodDeclarationSyntax>();
            //if (ancestors.Any())
            //{
            //    var method = ancestors.First();

            //    bool isFound = false;
            //    bool isAPMFollowed = false;
            //    foreach (var tmp in method.Body.ChildNodes())
            //    {
            //        if (isFound)
            //            isAPMFollowed = true;
            //        if (statement == tmp)
            //            isFound = true;
            //    }

            //    if (isAPMFollowed)
            //    {
            //        Result.apmDiagnosisResults.NumAPMBeginFollowed++;
            //        Logs.TempLog2.Info("APMFOLLOWED:\r\n{0}\r\n---------------------------------------------------", method);
                    
            //    }
            //}

            //SyntaxNode callbackBody = null;

            //if (callbackArg.Expression.Kind.ToString().Contains("IdentifierName"))
            //{
            //    var methodSymbol = SemanticModel.GetSymbolInfo(callbackArg.Expression).Symbol;

            //    if (methodSymbol.Kind.ToString().Equals("Method"))
            //        callbackBody = (MethodDeclarationSyntax)methodSymbol.DeclaringSyntaxReferences.First().GetSyntax();
            //}
            //else if (callbackArg.Expression.Kind.ToString().Contains("LambdaExpression"))
            //    callbackBody = node;

            //if (callbackBody != null)
            //{
            //    if (callbackBody.DescendantNodes().OfType<MemberAccessExpressionSyntax>().Any(a => a.Name.ToString().StartsWith("End")))
            //        Logs.TempLog3.Info("APMEND in Callback:\r\n{0}\r\nCaller: {1}\r\nDeclaringSyntaxNodes:\r\n{2}\r\n--------------------------------------------------", Document.FilePath, node, callbackBody);
            //    else
            //        Logs.TempLog3.Info("NO APMEND in Callback:\r\n{0}\r\nCaller: {1}\r\nDeclaringSyntaxNodes:\r\n{2}\r\n--------------------------------------------------", Document.FilePath, node, callbackBody);
            //}


            
        }
 private static bool IsInsideANullCheck(InvocationExpressionSyntax invocation, SemanticModel semanticModel, ISymbol symbol) =>
     invocation.Ancestors().OfType<IfStatementSyntax>().Any(@if => IsConditionThatChecksForNotEqualsNull(@if.Condition, semanticModel, symbol));
        private void AnalyzeInvocationExpression(DocumentData documentData, InvocationExpressionSyntax node, InvokeFunctionReferenceData functionReferenceData)
        {
            var functionData     = functionReferenceData.FunctionData;
            var methodSymbol     = functionReferenceData.ReferenceSymbol;
            var functionNode     = functionData.GetNode();
            var functionBodyNode = functionData.GetBodyNode();
            var queryExpression  = node.Ancestors()
                                   .TakeWhile(o => o != functionNode)
                                   .OfType <QueryExpressionSyntax>()
                                   .FirstOrDefault();

            if (queryExpression != null)             // Await is not supported in a linq query
            {
                functionReferenceData.Ignore = true;
                Logger.Warn($"Cannot await async method in a query expression:\r\n{queryExpression}\r\n");
                return;
            }

            var searchOptions = AsyncCounterpartsSearchOptions.Default;

            if (_configuration.UseCancellationTokenOverload)
            {
                searchOptions |= AsyncCounterpartsSearchOptions.HasCancellationToken;
            }
            functionReferenceData.ReferenceAsyncSymbols = new HashSet <IMethodSymbol>(GetAsyncCounterparts(methodSymbol.OriginalDefinition, searchOptions));
            if (functionReferenceData.ReferenceAsyncSymbols.Any())
            {
                if (functionReferenceData.ReferenceAsyncSymbols.All(o => o.ReturnsVoid || !o.ReturnType.IsTaskType()))
                {
                    functionReferenceData.AwaitInvocation = false;
                    Logger.Info($"Cannot await method that is either void or do not return a Task:\r\n{methodSymbol}\r\n");
                }
                var nameGroups = functionReferenceData.ReferenceAsyncSymbols.GroupBy(o => o.Name).ToList();
                if (nameGroups.Count == 1)
                {
                    functionReferenceData.AsyncCounterpartName = nameGroups[0].Key;
                }
            }
            else if (!ProjectData.Contains(functionReferenceData.ReferenceSymbol))
            {
                // If we are dealing with an external method and there are no async counterparts for it, we cannot convert it to async
                functionReferenceData.Ignore = true;
                Logger.Info($"Method {methodSymbol} can not be async as there is no async counterparts for it");
                return;
            }
            else if (functionReferenceData.ReferenceFunctionData != null)
            {
                functionReferenceData.AsyncCounterpartName = functionReferenceData.ReferenceSymbol.Name + "Async";
            }

            // If the invocation returns a Task then we need to analyze it further to see how the Task is handled
            if (methodSymbol.ReturnType.IsTaskType())
            {
                var retrunType   = (INamedTypeSymbol)methodSymbol.ReturnType;
                var canBeAwaited = false;
                var currNode     = node.Parent;
                while (true)
                {
                    var memberExpression = currNode as MemberAccessExpressionSyntax;
                    if (memberExpression == null)
                    {
                        break;
                    }
                    var memberName = memberExpression.Name.ToString();
                    if (retrunType.IsGenericType && memberName == "Result")
                    {
                        canBeAwaited = true;
                        break;
                    }
                    if (memberName == "ConfigureAwait")
                    {
                        var invocationNode = currNode.Parent as InvocationExpressionSyntax;
                        if (invocationNode != null)
                        {
                            functionReferenceData.ConfigureAwaitParameter = invocationNode.ArgumentList.Arguments.First().Expression;
                            currNode = invocationNode.Parent;
                            continue;
                        }
                        break;
                    }
                    if (memberName == "GetAwaiter")
                    {
                        var invocationNode = currNode.Parent as InvocationExpressionSyntax;
                        if (invocationNode != null)
                        {
                            currNode = invocationNode.Parent;
                            continue;
                        }
                        break;
                    }
                    if (_taskResultMethods.Contains(memberName))
                    {
                        var invocationNode = currNode.Parent as InvocationExpressionSyntax;
                        if (invocationNode != null)
                        {
                            canBeAwaited = true;
                        }
                    }
                    break;
                }
                if (!canBeAwaited)
                {
                    functionReferenceData.AwaitInvocation = false;
                    Logger.Info(
                        $"Cannot await invocation of a method that returns a Task without be synchronously awaited:\r\n{methodSymbol}\r\n");
                }
                else
                {
                    functionReferenceData.SynchronouslyAwaited = true;
                }
            }

            if (node.Parent.IsKind(SyntaxKind.ReturnStatement))
            {
                functionReferenceData.UseAsReturnValue = true;
            }

            // Calculate if node is the last statement
            if (node.Parent.Equals(functionBodyNode) ||       //eg. bool ExpressionReturn() => SimpleFile.Write();
                node.Equals(functionBodyNode)                 // eg. Func<bool> fn = () => SimpleFile.Write();
                )
            {
                functionReferenceData.LastInvocation   = true;
                functionReferenceData.UseAsReturnValue = !methodSymbol.ReturnsVoid;
            }
            var bodyBlock = functionBodyNode as BlockSyntax;

            if (bodyBlock?.Statements.Last() == node.Parent)
            {
                functionReferenceData.LastInvocation = true;
            }

            // Set CancellationTokenRequired if we detect that one of the async counterparts has a cancellation token as a parameter
            if (_configuration.UseCancellationTokenOverload &&
                functionReferenceData.ReferenceAsyncSymbols.Any(o => o.Parameters.Length > methodSymbol.Parameters.Length))
            {
                functionReferenceData.CancellationTokenRequired = true;
            }

            foreach (var analyzer in _configuration.InvocationExpressionAnalyzers)
            {
                analyzer.Analyze(node, functionReferenceData, documentData.SemanticModel);
            }

            // Propagate CancellationTokenRequired to the method data only if the invocation can be async
            if (functionReferenceData.CancellationTokenRequired && functionReferenceData.GetConversion() == ReferenceConversion.ToAsync)
            {
                // We need to set CancellationTokenRequired to true for the method that contains this invocation
                var methodData = functionReferenceData.FunctionData.GetMethodData();
                methodData.CancellationTokenRequired = true;
            }
        }
示例#27
0
        private T TransformFunctionReference <T>(T node, IFunctionAnalyzationResult funcResult, FunctionReferenceTransformationResult transfromReference,
                                                 ITypeTransformationMetadata typeMetadata,
                                                 INamespaceTransformationMetadata namespaceMetadata)
            where T : SyntaxNode
        {
            var nameNode                = node.GetAnnotatedNodes(transfromReference.Annotation).OfType <SimpleNameSyntax>().First();
            var funReferenceResult      = transfromReference.AnalyzationResult;
            var bodyFuncReferenceResult = funReferenceResult as IBodyFunctionReferenceAnalyzationResult;
            var newNameNode             = nameNode
                                          .WithIdentifier(Identifier(funReferenceResult.AsyncCounterpartName))
                                          .WithTriviaFrom(nameNode);

            transfromReference.Transformed = newNameNode;

            var cancellationTokenParamName = funcResult.GetMethodOrAccessor().CancellationTokenRequired ? "cancellationToken" : null;             // TODO: remove

            // If we have a cref change the name to the async counterpart and add/update arguments
            if (bodyFuncReferenceResult == null)
            {
                if (funReferenceResult.IsCref)
                {
                    var crefNode  = (NameMemberCrefSyntax)nameNode.Parent;
                    var paramList = new List <CrefParameterSyntax>();
                    // If the cref has already the parameters set then use them
                    if (crefNode.Parameters != null)
                    {
                        paramList.AddRange(crefNode.Parameters.Parameters);
                        // If the external async counterpart has a cancellation token, add it
                        if (funReferenceResult.AsyncCounterpartFunction == null &&
                            funReferenceResult.ReferenceSymbol.Parameters.Length <
                            funReferenceResult.AsyncCounterpartSymbol.Parameters.Length)
                        {
                            paramList.Add(CrefParameter(IdentifierName(nameof(CancellationToken))));
                        }
                    }
                    else
                    {
                        // We have to add the parameters to avoid ambiguity
                        var asyncSymbol = funReferenceResult.AsyncCounterpartSymbol;
                        paramList.AddRange(asyncSymbol.Parameters
                                           .Select(o => CrefParameter(o.Type
                                                                      .CreateTypeSyntax(true, namespaceMetadata.AnalyzationResult.IsIncluded(o.Type.ContainingNamespace?.ToString())))));
                    }

                    // If the async counterpart is internal and a token is required add a token parameter
                    if (funReferenceResult.AsyncCounterpartFunction?.GetMethodOrAccessor()?.CancellationTokenRequired == true)
                    {
                        paramList.Add(CrefParameter(IdentifierName(nameof(CancellationToken))));
                    }

                    node = node.ReplaceNestedNodes(
                        crefNode.Parent as QualifiedCrefSyntax,
                        crefNode,
                        crefNode
                        .ReplaceNode(nameNode, newNameNode)
                        .WithParameters(CrefParameterList(SeparatedList(paramList))),
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                          (type, fullName) => rootNode.WithContainer(type.CreateTypeSyntax(true, fullName).WithTriviaFrom(rootNode.Container))),
                        childNode => RunReferenceTransformers(childNode, funcResult, funReferenceResult, namespaceMetadata)
                        );
                }
                else if (funReferenceResult.IsNameOf)
                {
                    node = node.ReplaceNestedNodes(
                        nameNode.Parent as MemberAccessExpressionSyntax,
                        nameNode,
                        newNameNode,
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                          (type, fullName) => rootNode.WithExpression(type.CreateTypeSyntax(false, fullName).WithTriviaFrom(rootNode.Expression))),
                        childNode => RunReferenceTransformers(childNode, funcResult, funReferenceResult, namespaceMetadata)
                        );
                }
                return(node);
            }
            // If we have a method passed as an argument we need to check if we have to wrap it inside a function
            if (bodyFuncReferenceResult.AsyncDelegateArgument != null)
            {
                if (bodyFuncReferenceResult.WrapInsideFunction)
                {
                    // TODO: move to analyze step
                    var  argumentNode  = nameNode.Ancestors().OfType <ArgumentSyntax>().First();
                    var  delReturnType = (INamedTypeSymbol)bodyFuncReferenceResult.AsyncDelegateArgument.ReturnType;
                    var  returnType    = bodyFuncReferenceResult.AsyncCounterpartSymbol.ReturnType;
                    bool returnTypeMismatch;
                    if (bodyFuncReferenceResult.ReferenceFunction != null)
                    {
                        var refMethod = bodyFuncReferenceResult.ReferenceFunction as IMethodAnalyzationResult;
                        if (refMethod != null && refMethod.PreserveReturnType)
                        {
                            returnTypeMismatch = !delReturnType.Equals(returnType);   // TODO Generics
                        }
                        else if (delReturnType.IsGenericType)                         // Generic Task
                        {
                            returnTypeMismatch = delReturnType.TypeArguments.First().IsAwaitRequired(returnType);
                        }
                        else
                        {
                            returnTypeMismatch = delReturnType.IsAwaitRequired(returnType);
                        }
                    }
                    else
                    {
                        returnTypeMismatch = !delReturnType.Equals(returnType);                         // TODO Generics
                    }

                    var newArgumentExpression = argumentNode.Expression
                                                .ReplaceNestedNodes(
                        nameNode.Parent as MemberAccessExpressionSyntax,
                        nameNode,
                        newNameNode,
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                          (type, fullName) => rootNode.WithExpression(type.CreateTypeSyntax(false, fullName))),
                        childNode => RunReferenceTransformers(childNode, funcResult, funReferenceResult, namespaceMetadata)
                        )
                                                .WrapInsideFunction(bodyFuncReferenceResult.AsyncDelegateArgument, returnTypeMismatch,
                                                                    namespaceMetadata.TaskConflict,
                                                                    invocation => invocation.AddCancellationTokenArgumentIf(cancellationTokenParamName, bodyFuncReferenceResult));
                    node = node
                           .ReplaceNode(argumentNode.Expression, newArgumentExpression);
                }
                else
                {
                    node = node.ReplaceNestedNodes(
                        nameNode.Parent as MemberAccessExpressionSyntax,
                        nameNode,
                        newNameNode,
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                          (type, fullName) => rootNode.WithExpression(type.CreateTypeSyntax(false, fullName))),
                        childNode => RunReferenceTransformers(childNode, funcResult, funReferenceResult, namespaceMetadata)
                        );
                }
                return(node);
            }

            InvocationExpressionSyntax invokeNode = null;
            var isAccessor = bodyFuncReferenceResult.ReferenceSymbol.IsAccessor();

            if (!isAccessor && funReferenceResult.ReferenceNode.IsKind(SyntaxKind.InvocationExpression))
            {
                invokeNode = nameNode.Ancestors().OfType <InvocationExpressionSyntax>().First();
            }

            if (!bodyFuncReferenceResult.AwaitInvocation)
            {
                // An arrow method does not have a statement
                var statement = nameNode.Ancestors().OfType <StatementSyntax>().FirstOrDefault();
                var newNode   = (SyntaxNode)statement ?? node;

                if (invokeNode != null)
                {
                    newNode = newNode.ReplaceNestedNodes(
                        invokeNode,
                        nameNode,
                        newNameNode,
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode
                                                                          .AddCancellationTokenArgumentIf(cancellationTokenParamName, bodyFuncReferenceResult),
                                                                          funcResult, funReferenceResult, namespaceMetadata,
                                                                          (memberNode, type, fullName) => memberNode.WithExpression(type.CreateTypeSyntax(true, fullName).WithTriviaFrom(memberNode.Expression)))
                        );
                }
                else if (isAccessor)
                {
                    newNode = ConvertAccessor(newNode, nameNode, newNameNode, cancellationTokenParamName, bodyFuncReferenceResult,
                                              invNode => UpdateTypeAndRunReferenceTransformers(invNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                                               (memberNode, type, fullName) => memberNode.WithExpression(type.CreateTypeSyntax(true, fullName).WithTriviaFrom(memberNode.Expression))));
                }
                else
                {
                    newNode = newNode.ReplaceNestedNodes(
                        nameNode.Parent as MemberAccessExpressionSyntax,
                        nameNode,
                        newNameNode,
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                          (type, fullName) => rootNode.WithExpression(type.CreateTypeSyntax(false, fullName).WithTriviaFrom(rootNode.Expression))),
                        childNode => RunReferenceTransformers(childNode, funcResult, funReferenceResult, namespaceMetadata)
                        );
                }

                if (statement != null && !statement.IsKind(SyntaxKind.LocalFunctionStatement))
                {
                    if (bodyFuncReferenceResult.UseAsReturnValue)
                    {
                        newNode = ((StatementSyntax)newNode).ToReturnStatement();
                    }
                    node = node
                           .ReplaceNode(statement, newNode);
                }
                else
                {
                    node = (T)newNode;
                }
            }
            else
            {
                // We need to annotate the invocation node because of the AddAwait method as it needs the parent node
                var invokeAnnotation = Guid.NewGuid().ToString();
                if (isAccessor)
                {
                    node = ConvertAccessor(node, nameNode, newNameNode, cancellationTokenParamName, bodyFuncReferenceResult, invNode =>
                                           UpdateTypeAndRunReferenceTransformers(invNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                                 (memberNode, type, fullName) => memberNode.WithExpression(type.CreateTypeSyntax(true, fullName).WithTriviaFrom(memberNode.Expression)))
                                           .WithAdditionalAnnotations(new SyntaxAnnotation(invokeAnnotation))
                                           );
                }
                else
                {
                    node = node.ReplaceNestedNodes(
                        invokeNode,
                        nameNode,
                        newNameNode,
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode
                                                                          .AddCancellationTokenArgumentIf(cancellationTokenParamName, bodyFuncReferenceResult),
                                                                          funcResult, funReferenceResult, namespaceMetadata,
                                                                          (memberNode, type, fullName) => memberNode.WithExpression(type.CreateTypeSyntax(true, fullName).WithTriviaFrom(memberNode.Expression)))
                        .WithAdditionalAnnotations(new SyntaxAnnotation(invokeAnnotation))
                        );
                }

                invokeNode = node.GetAnnotatedNodes(invokeAnnotation).OfType <InvocationExpressionSyntax>().First();

                var conditionalAccessNode = invokeNode.Ancestors()
                                            .TakeWhile(o => !(o is StatementSyntax))
                                            .OfType <ConditionalAccessExpressionSyntax>()
                                            .FirstOrDefault();
                if (conditionalAccessNode != null)                 // ?. syntax
                {
                    var statement = (StatementSyntax)invokeNode.Ancestors().FirstOrDefault(o => o is StatementSyntax);
                    var block     = statement?.Parent as BlockSyntax;
                    if (statement == null || block == null)
                    {
                        // TODO: convert arrow method/property/function to a normal one
                        // TODO: convert to block if there is no block
                        node = node.ReplaceNode(conditionalAccessNode,
                                                conditionalAccessNode.AddAwait(_configuration.ConfigureAwaitArgument));
                    }
                    else
                    {
                        var fnName = nameNode.Identifier.ValueText;
                        // TODO: handle name collisions
                        var variableName             = $"{char.ToLowerInvariant(fnName[0])}{fnName.Substring(1)}Task";
                        var leadingTrivia            = statement.GetLeadingTrivia();
                        var newConditionalAccessNode = ConditionalAccessExpression(
                            conditionalAccessNode.Expression,
                            invokeNode)
                                                       .WithTriviaFrom(conditionalAccessNode);
                        var localVar = LocalDeclarationStatement(
                            VariableDeclaration(
                                IdentifierName(Identifier(leadingTrivia, "var", TriviaList(Space))),
                                SingletonSeparatedList(
                                    VariableDeclarator(
                                        Identifier(TriviaList(), variableName, TriviaList(Space)))
                                    .WithInitializer(
                                        EqualsValueClause(newConditionalAccessNode.WithoutTrivia())
                                        .WithEqualsToken(Token(TriviaList(), SyntaxKind.EqualsToken, TriviaList(Space)))
                                        )
                                    )))
                                       .WithSemicolonToken(Token(TriviaList(), SyntaxKind.SemicolonToken, TriviaList(typeMetadata.EndOfLineTrivia)));
                        var index = block.Statements.IndexOf(statement);

                        var lastReturnNode = block.DescendantNodes()
                                             .Where(o => o.SpanStart >= statement.SpanStart)
                                             .OfType <ReturnStatementSyntax>()
                                             .LastOrDefault();

                        var variableAnnotation = Guid.NewGuid().ToString();
                        var newBlock           = block.ReplaceNode(conditionalAccessNode,
                                                                   conditionalAccessNode.WhenNotNull.ReplaceNode(invokeNode,
                                                                                                                 IdentifierName(variableName)
                                                                                                                 .WithAdditionalAnnotations(new SyntaxAnnotation(variableAnnotation))
                                                                                                                 .WithLeadingTrivia(conditionalAccessNode.GetLeadingTrivia())
                                                                                                                 .WithTrailingTrivia(conditionalAccessNode.GetTrailingTrivia())
                                                                                                                 ));

                        var variable = newBlock.GetAnnotatedNodes(variableAnnotation).OfType <IdentifierNameSyntax>().First();
                        newBlock = newBlock.ReplaceNode(variable, variable.AddAwait(_configuration.ConfigureAwaitArgument));

                        var ifBlock = Block()
                                      .WithOpenBraceToken(
                            Token(TriviaList(leadingTrivia), SyntaxKind.OpenBraceToken, TriviaList(typeMetadata.EndOfLineTrivia)))
                                      .WithCloseBraceToken(
                            Token(TriviaList(leadingTrivia), SyntaxKind.CloseBraceToken, TriviaList(typeMetadata.EndOfLineTrivia)))
                                      .WithStatements(new SyntaxList <StatementSyntax>()
                                                      .AddRange(newBlock.AppendIndent(typeMetadata.IndentTrivia.ToFullString()).Statements.Skip(index)));

                        var ifStatement = IfStatement(
                            BinaryExpression(
                                SyntaxKind.NotEqualsExpression,
                                IdentifierName(Identifier(TriviaList(), variableName, TriviaList(Space))),
                                LiteralExpression(SyntaxKind.NullLiteralExpression))
                            .WithOperatorToken(
                                Token(TriviaList(), SyntaxKind.ExclamationEqualsToken, TriviaList(Space))),
                            ifBlock
                            )
                                          .WithIfKeyword(
                            Token(TriviaList(leadingTrivia), SyntaxKind.IfKeyword, TriviaList(Space)))
                                          .WithCloseParenToken(
                            Token(TriviaList(), SyntaxKind.CloseParenToken, TriviaList(typeMetadata.EndOfLineTrivia)));

                        var statements = new SyntaxList <StatementSyntax>()
                                         .AddRange(newBlock.Statements.Take(index))
                                         .Add(localVar)
                                         .Add(ifStatement);
                        if (lastReturnNode?.Expression != null)
                        {
                            // Check if the variable is defined otherwise return default return type value
                            if (lastReturnNode.Expression is IdentifierNameSyntax idNode &&
                                statements.OfType <VariableDeclaratorSyntax>().All(o => o.Identifier.ToString() != idNode.Identifier.ValueText))
                            {
                                lastReturnNode = lastReturnNode.WithExpression(DefaultExpression(funcResult.GetNode().GetReturnType().WithoutTrivia()));
                            }
                            statements = statements.Add(lastReturnNode);
                        }
                        node = node.ReplaceNode(block, newBlock.WithStatements(statements));
                    }
                }
                else
                {
                    node = node.ReplaceNode(invokeNode, invokeNode.AddAwait(_configuration.ConfigureAwaitArgument));
                }
            }
            return(node);
        }
示例#28
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, InvocationExpressionSyntax invocation)
        {
            if (CheckSpan(invocation, context.Span))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                IMethodSymbol methodSymbol = GetMethodSymbol(invocation, semanticModel, context.CancellationToken);

                if (methodSymbol != null)
                {
                    MethodDeclarationSyntax methodDeclaration = await GetMethodDeclarationAsync(methodSymbol, context.CancellationToken).ConfigureAwait(false);

                    if (methodDeclaration != null &&
                        !invocation.Ancestors().Any(f => f == methodDeclaration))
                    {
                        ExpressionSyntax expression = GetMethodExpression(methodDeclaration);

                        if (expression != null)
                        {
                            List <ParameterInfo> parameterInfos = GetParameterInfos(invocation, methodSymbol, semanticModel, context.CancellationToken);

                            if (parameterInfos != null)
                            {
                                INamedTypeSymbol enclosingType = semanticModel.GetEnclosingNamedType(invocation.SpanStart, context.CancellationToken);

                                SemanticModel declarationSemanticModel = (invocation.SyntaxTree == methodDeclaration.SyntaxTree)
                                    ? semanticModel
                                    : await context.Solution.GetDocument(methodDeclaration.SyntaxTree).GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

                                var refactoring = new InlineMethodExpressionRefactoring(context.Document, invocation, enclosingType, methodSymbol, methodDeclaration, parameterInfos.ToArray(), semanticModel, declarationSemanticModel, context.CancellationToken);

                                context.RegisterRefactoring("Inline method", c => refactoring.InlineMethodAsync(invocation, expression));

                                context.RegisterRefactoring("Inline and remove method", c => refactoring.InlineAndRemoveMethodAsync(invocation, expression));
                            }
                        }
                        else if (methodSymbol.ReturnsVoid &&
                                 invocation.IsParentKind(SyntaxKind.ExpressionStatement))
                        {
                            BlockSyntax body = methodDeclaration.Body;

                            if (body != null)
                            {
                                SyntaxList <StatementSyntax> statements = body.Statements;

                                if (statements.Any())
                                {
                                    List <ParameterInfo> parameterInfos = GetParameterInfos(invocation, methodSymbol, semanticModel, context.CancellationToken);

                                    if (parameterInfos != null)
                                    {
                                        var expressionStatement = (ExpressionStatementSyntax)invocation.Parent;

                                        INamedTypeSymbol enclosingType = semanticModel.GetEnclosingNamedType(invocation.SpanStart, context.CancellationToken);

                                        SemanticModel declarationSemanticModel = (invocation.SyntaxTree == methodDeclaration.SyntaxTree)
                                            ? semanticModel
                                            : await context.Solution.GetDocument(methodDeclaration.SyntaxTree).GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

                                        var refactoring = new InlineMethodStatementsRefactoring(context.Document, invocation, enclosingType, methodSymbol, methodDeclaration, parameterInfos.ToArray(), semanticModel, declarationSemanticModel, context.CancellationToken);

                                        context.RegisterRefactoring("Inline method", c => refactoring.InlineMethodAsync(expressionStatement, statements));

                                        context.RegisterRefactoring("Inline and remove method", c => refactoring.InlineAndRemoveMethodAsync(expressionStatement, statements));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
示例#29
0
        public bool isQueueInvocation(InvocationExpressionSyntax invocation, bool asynch, ExpressionSyntax success, out StatementSyntax result)
        {
            result = null;
            var signal = invocation.Expression as MemberAccessExpressionSyntax;

            if (signal == null)
            {
                return(false);
            }

            if (!(signal.Expression is IdentifierNameSyntax))
            {
                return(false);
            }

            var signalName = signal.Expression.ToString();

            if (asynch && !hasSignal(signalName))
            {
                return(false);
            }

            if (!asynch)
            {
                if (!invocation
                    .Ancestors()
                    .Where(node => node is ClassDeclarationSyntax)
                    .First()
                    .DescendantNodes()
                    .OfType <MethodDeclarationSyntax>()
                    .Where(method => method
                           .Identifier.ToString()
                           .Equals(signalName))
                    .Any())
                {
                    return(false);
                }
            }

            var queueName = "__queue" + signalName;

            switch (signal.Name.ToString())
            {
            case "enqueue":
                Debug.Assert(asynch);
                if (!hasMember(queueName))
                {
                    AddMember(Templates
                              .SignalQueueMember
                              .Get <MemberDeclarationSyntax>(queueName));
                }

                result = Templates
                         .Enqueue
                         .Get <StatementSyntax>(queueName, success);
                break;

            case "dequeue":
                result = asynch
                        ? Templates
                         .DequeueAsynch
                         .Get <StatementSyntax>(queueName, queueName + "_Top")
                        : Templates
                         .DequeueSynch
                         .Get <StatementSyntax>(queueName, queueName + "_Top");
                break;

            default:
                return(false);
            }

            return(true);
        }
 private static bool IsInsideANullCheck(InvocationExpressionSyntax invocation, SemanticModel semanticModel, ISymbol symbol) =>
 invocation.Ancestors().OfType <IfStatementSyntax>().Any(@if => IsConditionThatChecksForNotEqualsNull(@if.Condition, semanticModel, symbol));
        private T TransformFunctionReference <T>(T node, IFunctionAnalyzationResult funcResult, FunctionReferenceTransformationResult transfromReference,
                                                 ITypeTransformationMetadata typeMetadata,
                                                 INamespaceTransformationMetadata namespaceMetadata)
            where T : SyntaxNode
        {
            var nameNode                = node.GetAnnotatedNodes(transfromReference.Annotation).OfType <SimpleNameSyntax>().First();
            var funReferenceResult      = transfromReference.AnalyzationResult;
            var bodyFuncReferenceResult = funReferenceResult as IBodyFunctionReferenceAnalyzationResult;
            var newNameNode             = nameNode
                                          .WithIdentifier(Identifier(funReferenceResult.AsyncCounterpartName))
                                          .WithTriviaFrom(nameNode);

            transfromReference.Transformed = newNameNode;

            var cancellationTokenParamName = funcResult.GetMethodOrAccessor().CancellationTokenRequired ? "cancellationToken" : null;             // TODO: remove

            // If we have a cref change the name to the async counterpart and add/update arguments
            if (bodyFuncReferenceResult == null)
            {
                if (funReferenceResult.IsCref)
                {
                    var crefNode  = (NameMemberCrefSyntax)nameNode.Parent;
                    var paramList = new List <CrefParameterSyntax>();
                    // If the cref has already the parameters set then use them
                    if (crefNode.Parameters != null)
                    {
                        paramList.AddRange(crefNode.Parameters.Parameters);
                        // If the external async counterpart has a cancellation token, add it
                        if (funReferenceResult.AsyncCounterpartFunction == null &&
                            funReferenceResult.ReferenceSymbol.Parameters.Length <
                            funReferenceResult.AsyncCounterpartSymbol.Parameters.Length)
                        {
                            paramList.Add(CrefParameter(IdentifierName(nameof(CancellationToken))));
                        }
                    }
                    else
                    {
                        // We have to add the parameters to avoid ambiguity
                        var asyncSymbol = funReferenceResult.AsyncCounterpartSymbol;
                        paramList.AddRange(asyncSymbol.Parameters
                                           .Select(o => CrefParameter(o.Type
                                                                      .CreateTypeSyntax(true, namespaceMetadata.AnalyzationResult.IsIncluded(o.Type.ContainingNamespace?.ToString())))));
                    }

                    // If the async counterpart is internal and a token is required add a token parameter
                    if (funReferenceResult.AsyncCounterpartFunction?.GetMethodOrAccessor()?.CancellationTokenRequired == true)
                    {
                        paramList.Add(CrefParameter(IdentifierName(nameof(CancellationToken))));
                    }

                    node = node.ReplaceNestedNodes(
                        crefNode.Parent as QualifiedCrefSyntax,
                        crefNode,
                        crefNode
                        .ReplaceNode(nameNode, newNameNode)
                        .WithParameters(CrefParameterList(SeparatedList(paramList))),
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                          (type, fullName) => rootNode.WithContainer(type.CreateTypeSyntax(true, fullName).WithTriviaFrom(rootNode.Container))),
                        childNode => RunReferenceTransformers(childNode, funcResult, funReferenceResult, namespaceMetadata)
                        );
                }
                else if (funReferenceResult.IsNameOf)
                {
                    node = node.ReplaceNestedNodes(
                        nameNode.Parent as MemberAccessExpressionSyntax,
                        nameNode,
                        newNameNode,
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                          (type, fullName) => rootNode.WithExpression(type.CreateTypeSyntax(false, fullName).WithTriviaFrom(rootNode.Expression))),
                        childNode => RunReferenceTransformers(childNode, funcResult, funReferenceResult, namespaceMetadata)
                        );
                }
                return(node);
            }
            // If we have a method passed as an argument we need to check if we have to wrap it inside a function
            if (bodyFuncReferenceResult.AsyncDelegateArgument != null)
            {
                if (bodyFuncReferenceResult.WrapInsideFunction)
                {
                    // TODO: move to analyze step
                    var  argumentNode  = nameNode.Ancestors().OfType <ArgumentSyntax>().First();
                    var  delReturnType = (INamedTypeSymbol)bodyFuncReferenceResult.AsyncDelegateArgument.ReturnType;
                    var  returnType    = bodyFuncReferenceResult.AsyncCounterpartSymbol.ReturnType;
                    bool returnTypeMismatch;
                    if (bodyFuncReferenceResult.ReferenceFunction != null)
                    {
                        var refMethod = bodyFuncReferenceResult.ReferenceFunction as IMethodAnalyzationResult;
                        if (refMethod != null && refMethod.PreserveReturnType)
                        {
                            returnTypeMismatch = !delReturnType.Equals(returnType);   // TODO Generics
                        }
                        else if (delReturnType.IsGenericType)                         // Generic Task
                        {
                            returnTypeMismatch = delReturnType.TypeArguments.First().IsAwaitRequired(returnType);
                        }
                        else
                        {
                            returnTypeMismatch = delReturnType.IsAwaitRequired(returnType);
                        }
                    }
                    else
                    {
                        returnTypeMismatch = !delReturnType.Equals(returnType);                         // TODO Generics
                    }

                    var newArgumentExpression = argumentNode.Expression
                                                .ReplaceNestedNodes(
                        nameNode.Parent as MemberAccessExpressionSyntax,
                        nameNode,
                        newNameNode,
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                          (type, fullName) => rootNode.WithExpression(type.CreateTypeSyntax(false, fullName))),
                        childNode => RunReferenceTransformers(childNode, funcResult, funReferenceResult, namespaceMetadata)
                        )
                                                .WrapInsideFunction(bodyFuncReferenceResult.AsyncDelegateArgument, returnTypeMismatch,
                                                                    namespaceMetadata.TaskConflict,
                                                                    invocation => invocation.AddCancellationTokenArgumentIf(cancellationTokenParamName, bodyFuncReferenceResult));
                    node = node
                           .ReplaceNode(argumentNode.Expression, newArgumentExpression);
                }
                else
                {
                    node = node.ReplaceNestedNodes(
                        nameNode.Parent as MemberAccessExpressionSyntax,
                        nameNode,
                        newNameNode,
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                          (type, fullName) => rootNode.WithExpression(type.CreateTypeSyntax(false, fullName))),
                        childNode => RunReferenceTransformers(childNode, funcResult, funReferenceResult, namespaceMetadata)
                        );
                }
                return(node);
            }

            InvocationExpressionSyntax invokeNode = null;
            var isAccessor = bodyFuncReferenceResult.ReferenceSymbol.IsAccessor();

            if (!isAccessor && funReferenceResult.ReferenceNode.IsKind(SyntaxKind.InvocationExpression))
            {
                invokeNode = nameNode.Ancestors().OfType <InvocationExpressionSyntax>().First();
            }

            if (!bodyFuncReferenceResult.AwaitInvocation)
            {
                // An arrow method does not have a statement
                var statement = nameNode.Ancestors().OfType <StatementSyntax>().FirstOrDefault();
                var statementInParentFunction = nameNode.Ancestors().TakeWhile(o => !o.Equals(statement)).Any(o => o.IsFunction());
                var newNode = (SyntaxNode)statement ?? node;

                if (invokeNode != null)
                {
                    newNode = newNode.ReplaceNestedNodes(
                        invokeNode,
                        nameNode,
                        newNameNode,
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode
                                                                          .AddCancellationTokenArgumentIf(cancellationTokenParamName, bodyFuncReferenceResult),
                                                                          funcResult, funReferenceResult, namespaceMetadata,
                                                                          (memberNode, type, fullName) => memberNode.WithExpression(type.CreateTypeSyntax(true, fullName).WithTriviaFrom(memberNode.Expression)))
                        );
                }
                else if (isAccessor)
                {
                    newNode = ConvertAccessor(newNode, nameNode, newNameNode, cancellationTokenParamName, bodyFuncReferenceResult,
                                              invNode => UpdateTypeAndRunReferenceTransformers(invNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                                               (memberNode, type, fullName) => memberNode.WithExpression(type.CreateTypeSyntax(true, fullName).WithTriviaFrom(memberNode.Expression))));
                }
                else
                {
                    newNode = newNode.ReplaceNestedNodes(
                        nameNode.Parent as MemberAccessExpressionSyntax,
                        nameNode,
                        newNameNode,
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                          (type, fullName) => rootNode.WithExpression(type.CreateTypeSyntax(false, fullName).WithTriviaFrom(rootNode.Expression))),
                        childNode => RunReferenceTransformers(childNode, funcResult, funReferenceResult, namespaceMetadata)
                        );
                }

                if (statement != null && !statement.IsKind(SyntaxKind.LocalFunctionStatement))
                {
                    // Skip adding return statement for arrow functions
                    if (bodyFuncReferenceResult.UseAsReturnValue && !statementInParentFunction)
                    {
                        newNode = ((StatementSyntax)newNode).ToReturnStatement();
                    }
                    node = node
                           .ReplaceNode(statement, newNode);
                }
                else
                {
                    node = (T)newNode;
                }
            }
            else
            {
                // We need to annotate the invocation node because of the AddAwait method as it needs the parent node
                var invokeAnnotation = Guid.NewGuid().ToString();
                if (isAccessor)
                {
                    node = ConvertAccessor(node, nameNode, newNameNode, cancellationTokenParamName, bodyFuncReferenceResult, invNode =>
                                           UpdateTypeAndRunReferenceTransformers(invNode, funcResult, funReferenceResult, namespaceMetadata,
                                                                                 (memberNode, type, fullName) => memberNode.WithExpression(type.CreateTypeSyntax(true, fullName).WithTriviaFrom(memberNode.Expression)))
                                           .WithAdditionalAnnotations(new SyntaxAnnotation(invokeAnnotation))
                                           );
                }
                else
                {
                    node = node.ReplaceNestedNodes(
                        invokeNode,
                        nameNode,
                        newNameNode,
                        rootNode => UpdateTypeAndRunReferenceTransformers(rootNode
                                                                          .AddCancellationTokenArgumentIf(cancellationTokenParamName, bodyFuncReferenceResult),
                                                                          funcResult, funReferenceResult, namespaceMetadata,
                                                                          (memberNode, type, fullName) => memberNode.WithExpression(type.CreateTypeSyntax(true, fullName).WithTriviaFrom(memberNode.Expression)))
                        .WithAdditionalAnnotations(new SyntaxAnnotation(invokeAnnotation))
                        );
                }

                invokeNode = node.GetAnnotatedNodes(invokeAnnotation).OfType <InvocationExpressionSyntax>().First();

                // Check if the invocation has a ?.
                var conditionalAccessNode = invokeNode.Ancestors()
                                            .TakeWhile(o => !(o is StatementSyntax))
                                            .OfType <ConditionalAccessExpressionSyntax>()
                                            .FirstOrDefault(o => o.WhenNotNull.Contains(invokeNode));
                if (conditionalAccessNode != null)                 // ?. syntax
                {
                    // We have to find out which strategy to use, if we have a non assignable expression, we are force to use if statements
                    // otherwise a ternary condition will be used
                    if (!conditionalAccessNode.Parent.IsKind(SyntaxKind.ExpressionStatement) || !invokeNode.Equals(conditionalAccessNode.WhenNotNull))
                    {
                        node = TransformConditionalAccessToConditionalExpressions(node, nameNode, funReferenceResult, typeMetadata,
                                                                                  conditionalAccessNode, invokeNode);
                    }
                    else
                    {
                        node = TransformConditionalAccessToIfStatements(node, nameNode, typeMetadata, conditionalAccessNode, invokeNode);
                    }
                }
                else
                {
                    node = node.ReplaceNode(invokeNode, invokeNode.AddAwait(_configuration.ConfigureAwaitArgument));
                }
            }
            return(node);
        }
        public override void VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            var symbol = (IMethodSymbol)SemanticModel.GetSymbolInfo(node).Symbol;

            if (symbol != null)
            {
                if (symbol.IsAPMBeginMethod())
                    APMDiagnosisDetection(symbol, node);

                if (symbol.IsAPMEndMethod())
                {
                    Result.apmDiagnosisResults.NumAPMEndMethods++;


                    var tmp = node.ArgumentList.Arguments.First().DescendantNodes().OfType<IdentifierNameSyntax>(); 
                    
                    if(tmp.Any())
                    {
                        var id = tmp.First();

                        if(node.Ancestors().OfType<BlockSyntax>().First().DescendantNodes().OfType<IdentifierNameSyntax>().Where(a=> (a.Identifier.ToString()== id.Identifier.ToString())).Count()>2)
                            Logs.TempLog3.Info("IAsyncResultSomewhereElse {0}\r\n{1}\r\n--------------------", Document.FilePath, node.Ancestors().OfType<BlockSyntax>().First());

                    }
                    

                   


                    //var ancestors2 = node.Ancestors().OfType<TryStatementSyntax>();
                    //if (ancestors2.Any())
                    //{
                    //    Logs.TempLog4.Info("TRYCATCHED ENDXXX:\r\n{0}\r\n---------------------------------------------------", ancestors2.First());
                    //    Result.apmDiagnosisResults.NumAPMEndTryCatchedMethods++;
                    //}

                    //SyntaxNode block = null;
                    //var lambdas = node.Ancestors().OfType<SimpleLambdaExpressionSyntax>();
                    //if (lambdas.Any())
                    //{
                    //    block = lambdas.First();
                    //}

                    //if (block == null)
                    //{
                    //    var lambdas2 = node.Ancestors().OfType<ParenthesizedLambdaExpressionSyntax>();
                    //    if (lambdas2.Any())
                    //        block = lambdas2.First();
                    //}

                    //if (block == null)
                    //{
                    //    var ancestors3 = node.Ancestors().OfType<MethodDeclarationSyntax>();
                    //    if (ancestors3.Any())
                    //        block = ancestors3.First();

                    //}

                    //if (block != null)
                    //{
                    //    if (block.DescendantNodes().OfType<MemberAccessExpressionSyntax>().Any(a => a.Name.ToString().StartsWith("Begin") && !a.Name.ToString().Equals("BeginInvoke")))
                    //    {
                    //        Logs.TempLog5.Info("NESTED ENDXXX:\r\n{0}\r\n---------------------------------------------------", block);
                    //        Result.apmDiagnosisResults.NumAPMEndNestedMethods++;
                    //    }
                    //}

                }
            }

            base.VisitInvocationExpression(node);
        }
示例#33
0
            private void AnalyzeInvocation(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax node, IMethodSymbol method)
            {
                var invocationNodes = node.Parent.Ancestors().OfType <InvocationExpressionSyntax>().ToArray();

                var invocations = (from i in invocationNodes
                                   let sym = context.SemanticModel.GetSymbolInfo(i)
                                             where sym.Symbol?.Kind == SymbolKind.Method
                                             let methodSymbol = (IMethodSymbol)sym.Symbol
                                                                select new StructureMapConfigurationInvocation(methodSymbol, i)).ToArray();

                ITypeSymbol    plugin;
                LamarLifecycle lifecycle = null;

                if (method.Name.Equals("ForSingletonOf"))
                {
                    lifecycle = LamarLifecycle.Singleton;
                }

                var assignment = node.Ancestors().OfType <AssignmentExpressionSyntax>().FirstOrDefault();

                ISymbol assignedTo = null;

                if (assignment != null)
                {
                    assignedTo = context.SemanticModel.GetSymbolInfo(assignment.Left).Symbol;
                }

                var variableDeclaration = node.Ancestors().OfType <VariableDeclarationSyntax>().FirstOrDefault();

                if (variableDeclaration != null)
                {
                    assignedTo = context.SemanticModel.GetDeclaredSymbol(variableDeclaration.Variables[0]);
                }

                ITypeSymbol PluginFromArgument(ExpressionSyntax expr)
                {
                    // ReSharper disable once ConvertIfStatementToSwitchStatement
                    if (expr is TypeOfExpressionSyntax toe)
                    {
                        var typeInfo = context.SemanticModel.GetTypeInfo(toe.Type);
                        return(typeInfo.Type);
                    }

                    // ReSharper disable once InvertIf
                    if (expr is InvocationExpressionSyntax ies && ies.Expression is MemberAccessExpressionSyntax mes)
                    {
                        var sym = context.SemanticModel.GetSymbolInfo(ies);
                        // ReSharper disable once InvertIf
                        if (sym.Symbol != null && sym.Symbol.Name.Equals("GetType"))
                        {
                            var typeInfo = context.SemanticModel.GetTypeInfo(mes.Expression);
                            return(typeInfo.Type);
                        }
                    }

                    if (expr is IdentifierNameSyntax ins)
                    {
                        var sym = context.SemanticModel.GetTypeInfo(ins);
                        return(sym.Type);
                    }

                    return(null);
                }

                LamarLifecycle LifecycleFromArgument(ExpressionSyntax expr)
                {
                    var lifecycleType = context.SemanticModel.GetTypeInfo(expr).Type;

                    return(LifecycleMap[lifecycleType.ToDisplayString()]);
                }

                if (method.IsGenericMethod)
                {
                    plugin = method.TypeArguments[0];

                    if (node.ArgumentList.Arguments.Count > 0)
                    {
                        lifecycle = LifecycleFromArgument(node.ArgumentList.Arguments[0].Expression);
                    }
                }
                else
                {
                    var expr = node.ArgumentList.Arguments[0].Expression;

                    plugin = PluginFromArgument(expr);
                }

                if (plugin == null)
                {
                    return;
                }

                LamarLifecycle FromInvocation(StructureMapConfigurationInvocation i)
                {
                    switch (i.MethodSymbol.Name)
                    {
                    case "Singleton":
                    {
                        return(LamarLifecycle.Singleton);
                    }

                    case "Scoped":
                    {
                        return(LamarLifecycle.Scoped);
                    }

                    case "Transient":
                    {
                        return(LamarLifecycle.Transient);
                    }

                    default:
                    {
                        return(null);
                    }
                    }
                }

                lifecycle = lifecycle ?? invocations.Select(FromInvocation).FirstOrDefault(x => x != null) ?? LamarLifecycle.TransientImplicit;

                var concretesPluggedBy = new[] { "Use", "Add" };

                var concretePluginInvocation =
                    invocations.FirstOrDefault(x => concretesPluggedBy.Any(s => s.Equals(x.MethodSymbol.Name, StringComparison.Ordinal)));

                var concretePlugin = plugin;

                ITypeSymbol ConcretePluginFrom(StructureMapConfigurationInvocation invocation)
                {
                    if (invocation.MethodSymbol.IsGenericMethod)
                    {
                        return(invocation.MethodSymbol.TypeArguments[0]);
                    }

                    var expr           = invocation.Invocation.ArgumentList.Arguments[invocation.Invocation.ArgumentList.Arguments.Count - 1].Expression;
                    var pluginToReturn = PluginFromArgument(expr);

                    if (pluginToReturn == null)
                    {
                        if (expr is LambdaExpressionSyntax les)
                        {
                            var bodyType = context.SemanticModel.GetTypeInfo(les.Body);
                            return(bodyType.Type ?? (context.SemanticModel.GetSymbolInfo(expr).Symbol as IMethodSymbol)?.ReturnType);
                        }
                    }

                    return(pluginToReturn);
                }

                if (concretePluginInvocation != null)
                {
                    concretePlugin = ConcretePluginFrom(concretePluginInvocation);
                }

                var assembly = context.Compilation.Assembly;

                var wiringCtx = new LamarWiringCtx(node, plugin, lifecycle, assembly, concretePlugin, assignedTo);

                host.wirings.Add(wiringCtx);
            }
        // puts the correct arguments in the register statement
        private async Task<Document> CorrectArgumentsAsync(Document document, InvocationExpressionSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            string methodName = CodeFixHelper.GetRegisterMethodName(declaration);

            ClassDeclarationSyntax classDeclaration = declaration.AncestorsAndSelf().OfType<ClassDeclarationSyntax>().First();
            methodName = CodeFixHelper.GetExistingAnalysisMethodName(classDeclaration);

            if (methodName == null)
            {
                methodName = "AnalyzeIfStatement";
            }

            SyntaxNode statement = CodeFixHelper.CreateRegister(generator, declaration.Ancestors().OfType<MethodDeclarationSyntax>().First(), methodName);
            SyntaxNode expression = generator.ExpressionStatement(statement);

            return await ReplaceNode(declaration.Parent, expression.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ParseLeadingTrivia("// Calls the method (first argument) to perform analysis whenever a SyntaxNode of kind IfStatement is found").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }
示例#35
0
        public override void VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            string expression = node.Expression.ToString();

            if (expression == _pattern)
            {
                string nodeValue = node.ToString();

                if (Matches.ContainsKey(nodeValue))
                {
                    Matches[nodeValue] += 1;
                }
                else
                {
                    Matches.Add(nodeValue, 1);
                }

                var a1 = node.Ancestors()
                         .Where(x => x.IsKind(SyntaxKind.ClassStatement))
                         .Cast <ClassStatementSyntax>().ToList();

                var a2 = node.Ancestors()
                         .Where(x => x.IsKind(SyntaxKind.FunctionStatement) || x.IsKind(SyntaxKind.SubStatement))
                         .Cast <MethodStatementSyntax>().ToList();

                var a3 = node.Ancestors()
                         .Where(x => x.IsKind(SyntaxKind.ClassBlock))
                         .Cast <ClassBlockSyntax>().ToList();

                var a3a = node.Ancestors()
                          .Where(x => x.IsKind(SyntaxKind.ModuleBlock))
                          .Cast <ModuleBlockSyntax>().ToList();

                var a4 = node.Ancestors()
                         .Where(x => x.IsKind(SyntaxKind.FunctionBlock) || x.IsKind(SyntaxKind.SubBlock))
                         .Cast <MethodBlockSyntax>().ToList();

                var a5 = node.Ancestors()
                         .Where(x => x.IsKind(SyntaxKind.FunctionBlock) || x.IsKind(SyntaxKind.SubBlock))
                         .Cast <MethodBlockSyntax>().ToList();

                string className  = "unknown";
                string moduleName = "unknown";
                string typeName   = "unknown";
                string methodName = "none";

                if (a3.Count > 0)
                {
                    typeName = "Class";

                    className = node.Ancestors()
                                .Where(x => x.IsKind(SyntaxKind.ClassBlock))
                                .Cast <ClassBlockSyntax>().First().ClassStatement.Identifier.ToString();
                }

                if (a3a.Count > 0)
                {
                    typeName = "Module";

                    moduleName = node.Ancestors()
                                 .Where(x => x.IsKind(SyntaxKind.ModuleBlock))
                                 .Cast <ModuleBlockSyntax>().First().ModuleStatement.Identifier.ToString();
                }

                if (a5.Count > 0)
                {
                    methodName = node.Ancestors()
                                 .Where(x => x.IsKind(SyntaxKind.FunctionBlock) || x.IsKind(SyntaxKind.SubBlock))
                                 .Cast <MethodBlockSyntax>().First().SubOrFunctionStatement.Identifier.ToString();
                }

                //string className = node.Ancestors()
                //    .Where(x => x.IsKind(SyntaxKind.ClassStatement))
                //    .Cast<ClassStatementSyntax>().First().ToString();

                //string methodName = node.Ancestors()
                //    .Where(x => x.IsKind(SyntaxKind.FunctionStatement) || x.IsKind(SyntaxKind.SubStatement))
                //    .Cast<MethodStatementSyntax>().First().ToString();

                //StringBuilder.AppendLine(String.Format("{0,6}:({1,-25})  Method:({2,-35}) {3}",
                //    typeName,
                //    typeName == "Class" ? className : moduleName,
                //    Helpers.VB.GetContainingMethod(node), nodeValue));

                string messageContext = "";

                if (DisplayClassOrModuleName)
                {
                    // HACK(crhodes)
                    // Figure out how to get Helpers to work

                    messageContext = Helpers.VB.GetContainingContext(node, Display);
                }

                if (DisplayMethodName)
                {
                    // HACK(crhodes)
                    // Figure out how to get Helpers to work

                    messageContext += string.Format(" Method:({0, -35})", Helpers.VB.GetContainingMethodName(node));
                }

                Messages.AppendLine(String.Format("{0} {1}",
                                                  messageContext,
                                                  nodeValue));
            }

            // Call base to visit children

            base.VisitInvocationExpression(node);
        }
示例#36
0
        private void ProcessEmitVertex(InvocationExpressionSyntax node)
        {
            var model = GetModel(node);
            DataFlowAnalysis analysis = null;

            if (_lastVertexEmit is ExpressionSyntax expression)
            {
                analysis = model.AnalyzeDataFlow(expression);
            }
            else if (_lastVertexEmit is StatementSyntax lastStatement)
            {
                var emitStatement = node.Ancestors().OfType <StatementSyntax>().FirstOrDefault();
                if (lastStatement.Parent != emitStatement.Parent)
                {
                    lastStatement = emitStatement.Parent.ChildNodes().Cast <StatementSyntax>().First();
                }
                analysis        = model.AnalyzeDataFlow(lastStatement, emitStatement);
                _lastVertexEmit = emitStatement;
            }

            var emit = model.GetSymbolInfo(node.ArgumentList.Arguments.Last().Expression);

            if (!(emit.Symbol is IFieldSymbol emitParam))
            {
                throw new ShaderGenerationException("EmitVertex argument must be a field");
            }
            var emitAttribute = emit.Symbol.GetAttributes().FirstOrDefault(a => a.AttributeClass.Name.Contains("EmitVertex"));

            if (emitAttribute == null)
            {
                throw new ShaderGenerationException("EmitVertex arguments must be marked with EmitVertexAttribute");
            }

            int streamId = 0;

            if (node.ArgumentList.Arguments.Count > 1)
            {
                streamId = (int)model.GetConstantValue(node.ArgumentList.Arguments.First()).Value;
            }

            var assignments = analysis.AlwaysAssigned.Concat(_writeFields);

            if (!_emittedData.TryGetValue(streamId, out var emissions))
            {
                emissions = new HashSet <ISymbol>(assignments.OfType <IFieldSymbol>(), SymbolEqualityComparer.Default);
                _emittedData.Add(streamId, emissions);
                if (assignments.Contains(emitParam))
                {
                    emissions.Add(emitParam);
                }
            }

            if (analysis != null)
            {
                foreach (var emission in emissions)
                {
                    if (!assignments.Contains(emission) && !assignments.Contains(emission.ContainingType))
                    {
                        var type = (emission as IFieldSymbol)?.Type ?? (emission as IParameterSymbol)?.Type;
                        if (type == null || !type.GetMembers().OfType <IFieldSymbol>().All(assignments.Contains))
                        {
                            throw new ShaderGenerationException($"{emission.Name} must be fully assigned before every call to EmitVertex");
                        }
                    }
                }
                foreach (var assignment in assignments.OfType <IFieldSymbol>().Append <ISymbol>(emitParam).Where(a => !emissions.Contains(a)))
                {
                    var type = (assignment as IFieldSymbol)?.Type ?? (assignment as IParameterSymbol)?.Type;
                    if (type == null || !type.GetMembers().OfType <IFieldSymbol>().All(emissions.Contains))
                    {
                        throw new ShaderGenerationException($"{assignment.Name} must be fully assigned before every call to EmitVertex");
                    }
                }
            }
            _writeFields.Clear();
        }
 private static bool IsInsideANullCheck(InvocationExpressionSyntax invocation, SemanticModel semanticModel, ISymbol symbol)
 {
     var ifs = invocation.Ancestors().OfType<IfStatementSyntax>();
     foreach (IfStatementSyntax @if in ifs)
     {
         if ([email protected]?.IsKind(SyntaxKind.NotEqualsExpression) ?? true) continue;
         var equals = (BinaryExpressionSyntax)@if.Condition;
         if (equals.Left == null || equals.Right == null) continue;
         ISymbol identifierSymbol;
         if (equals.Right.IsKind(SyntaxKind.NullLiteralExpression) && equals.Left.IsKind(SyntaxKind.IdentifierName))
             identifierSymbol = semanticModel.GetSymbolInfo(equals.Left).Symbol;
         else if (equals.Left.IsKind(SyntaxKind.NullLiteralExpression) && equals.Right.IsKind(SyntaxKind.IdentifierName))
             identifierSymbol = semanticModel.GetSymbolInfo(equals.Right).Symbol;
         else continue;
         if (symbol.Equals(identifierSymbol)) return true;
     }
     return false;
 }