예제 #1
0
        private static string Block(BlockSyntax node, bool braces = true)
        {
            var output = (braces ? "{" + NewLine : "");

            output += string.Join("", node.ChildNodes().Select(SyntaxNode));

            return output + (braces ? "}" + NewLine + NewLine : "");
        }
예제 #2
0
            public override void VisitBlock(BlockSyntax node)
            {
                var statements = node.ChildNodes().OfType<ExpressionStatementSyntax>();
                var invocations = statements.Select(s => s.Expression).OfType<InvocationExpressionSyntax>();
                var glOperators = invocations.Select(i => i.Expression).OfType<MemberAccessExpressionSyntax>()
                    .Where(m => m.IsKind(SyntaxKind.SimpleMemberAccessExpression)).Where(s => s.GetFirstToken().Text == nameof(GL));
                var beginEnds = glOperators.Select(g => Tuple.Create(g.Parent as InvocationExpressionSyntax, g.ChildNodes().Skip(1).FirstOrDefault()?.GetFirstToken().Text))
                    .Where(p => p.Item2 == nameof(GL.Begin) || p.Item2 == nameof(GL.End));

                // filtering
                if (!beginEnds.Any())
                {
                    base.VisitBlock(node);
                    return;
                }

                // block contains GL.Begin() or GL.End()
                var counter = 0;
                Location prevBeginLocation = null;
                foreach (var pair in beginEnds)
                {
                    if (pair.Item2 == nameof(GL.Begin))
                    {
                        counter++;
                        if (counter > 1)
                        {
                            Diagnostics.Add(Diagnostic.Create(
                                descriptor: Rule,
                                location: prevBeginLocation,
                                messageArgs: nameof(GL) + "." + nameof(GL.End)));
                            counter = 1;
                        }
                        prevBeginLocation = pair.Item1.GetLocation();
                    }
                    else if (pair.Item2 == nameof(GL.End))
                    {
                        counter--;
                        if (counter < 0)
                        {
                            Diagnostics.Add(Diagnostic.Create(
                                descriptor: Rule,
                                location: pair.Item1.GetLocation(),
                                messageArgs: nameof(GL) + "." + nameof(GL.Begin)));
                            counter = 0;
                        }
                    }
                }
                if (counter > 0)
                {
                    Diagnostics.Add(Diagnostic.Create(
                        descriptor: Rule,
                        location: prevBeginLocation,
                        messageArgs: nameof(GL) + "." + nameof(GL.End)));
                }

                base.VisitBlock(node);
            }
        public override SyntaxNode VisitBlock(BlockSyntax node)
        {
            var value = base.VisitBlock(node);
            if (_isExpressionTransformer && _transform && node.Parent is MethodDeclarationSyntax)
            {
                _isExpressionTransformer = false;
                _transform = false;
                var newStatements = new[] { string.Concat("value = new ", _expressionTransformerNamespaceDot, _edmxName, @"ExpressionTransformer().TransformExpression(expression, contextName);"), @"
            if (value != expression)
                return value;" };

                var statements = node.ChildNodes().OfType<StatementSyntax>().ToList();
                return node.DefineStatements(statements.Take(statements.Count - 1).Union(newStatements.Select(s => Syntax.ParseStatement(s))).Union(new[] { statements[statements.Count - 1] }));
            }
            return value;
        }
        private async Task <Solution> SwagifyEndpoint(Document doc, MethodDeclarationSyntax method,
                                                      CancellationToken cancellationToken)
        {
            SyntaxNode root = await doc.GetSyntaxRootAsync(cancellationToken);

            BlockSyntax methodBlock = method.ChildNodes().First(m => m is BlockSyntax) as BlockSyntax;

            /* Get SwaggerResponse attributes:
             * att.Attributes[0] is always the name of the attribute
             * (I think, it could be something like assembly:) TODO */
            List <AttributeListSyntax> swaggerResponses    = new List <AttributeListSyntax>();
            List <AttributeListSyntax> remainingAttributes = new List <AttributeListSyntax>();

            foreach (AttributeListSyntax att in method.AttributeLists)
            {
                if (att.GetName() == AttributeName)
                {
                    swaggerResponses.Add(att);
                }
                else
                {
                    remainingAttributes.Add(att);
                }
            }

            /* TODO: check BlockSyntaxes for returns */
            List <ReturnStatementSyntax> returnStatements = methodBlock.ChildNodes().OfType <ReturnStatementSyntax>().ToList();

            Dictionary <HttpStatusCode, AttributeMetadata> responses = GetAttributeSummaries(swaggerResponses);
            /* Clone dictionary for working, keep returnTypes for the original */
            Dictionary <HttpStatusCode, AttributeMetadata> responsesUpdated =
                responses.ToDictionary(a => a.Key, b => new AttributeMetadata(b.Value.StatusCode, b.Value.Description, b.Value.TypeName));

            for (int index = 0; index < returnStatements.Count; index++)
            {
                ReturnStatementSyntax returnStatement = returnStatements[index];
                HttpStatusCode        statusCode      = GetReturnCode(returnStatement);

                /* Get the type and update it. If the types are the same,
                 * nothing will change. */
                string type = GetReturnTypeName(returnStatement);
                if (responsesUpdated.ContainsKey(statusCode))
                {
                    responsesUpdated[statusCode].TypeName = type;
                }
                else
                {
                    responsesUpdated[statusCode] =
                        new AttributeMetadata(statusCode, DescriptionPlaceholder, type);
                }
            }
            /* Check if a change is required */

            if (!IsRefactorRequired(responses, responsesUpdated))
            {
                /* No change required */
                return(null);
            }

            /* Commit refactoring */
            SyntaxList <AttributeListSyntax> newAttributes = DoRefactor(responsesUpdated, method);

            Solution swagSolution = doc.WithSyntaxRoot(root.ReplaceNode(
                                                           method, method.WithAttributeLists(newAttributes))).Project.Solution;

            return(swagSolution);
        }
예제 #5
0
            public override void VisitBlock(BlockSyntax node)
            {
                var statements = node.ChildNodes().OfType<ExpressionStatementSyntax>();
                var invocations = statements.Select(s => s.Expression).OfType<InvocationExpressionSyntax>();
                var glOperators = invocations.Select(i => i.Expression).OfType<MemberAccessExpressionSyntax>()
                    .Where(m => m.IsKind(SyntaxKind.SimpleMemberAccessExpression)).Where(s => s.GetFirstToken().Text == nameof(GL));
                var pushPops = glOperators.Select(g => Tuple.Create(g.Parent as InvocationExpressionSyntax, g.ChildNodes().Skip(1).First().GetFirstToken().Text))
                    .Where(p => p.Item2.StartsWith("Push") || p.Item2.StartsWith("Pop"));

                // filtering
                if (!pushPops.Any())
                {
                    base.VisitBlock(node);
                    return;
                }

                // block contains GL.Push???() or GL.Pop???
                var counters = new int[reverseRouter.Count]; // new int[5]
                var prevPushLocations = new Location[reverseRouter.Count]; // new Location[5]
                foreach (var pair in pushPops)
                {
                    var route = router[pair.Item2];
                    if (pair.Item2.StartsWith("Push"))
                    {
                        counters[route]++;
                        if (counters[route] > 1)
                        {
                            Diagnostics.Add(Diagnostic.Create(
                                descriptor: Rule,
                                location: prevPushLocations[route],
                                messageArgs: nameof(GL) + ".Pop" + reverseRouter[route]));
                            counters[router[pair.Item2]] = 1;
                        }
                        prevPushLocations[route] = pair.Item1.GetLocation();
                    }
                    else if (pair.Item2.StartsWith("Pop"))
                    {
                        counters[route]--;
                        if (counters[route] < 0)
                        {
                            Diagnostics.Add(Diagnostic.Create(
                                descriptor: Rule,
                                location: pair.Item1.GetLocation(),
                                messageArgs: nameof(GL) + ".Push" + reverseRouter[route]));
                            counters[route] = 0;
                        }
                    }
                }
                for (int i = 0; i < counters.Length; i++)
                {
                    if (counters[i] > 0)
                    {
                        Diagnostics.Add(Diagnostic.Create(
                            descriptor: Rule,
                            location: prevPushLocations[i],
                            messageArgs: nameof(GL) + ".Pop" + reverseRouter[i]));
                    }
                }

                base.VisitBlock(node);
            }
예제 #6
0
 private static bool HasStatementsCount(BlockSyntax methodBody, int expectedStatementsCount)
 {
     return(methodBody.ChildNodes().Count() == expectedStatementsCount);
 }
예제 #7
0
        private void ProcessChild(SyntaxNode syntaxNode, NodeDetails previousNodeDetails)
        {
            switch (syntaxNode.Kind())
            {
            case SyntaxKind.ClassDeclaration:
            {
                ClassDeclarationSyntax classDeclarationSyntax = (ClassDeclarationSyntax)syntaxNode;

                if (classDeclarationSyntax.AttributeLists.Count > 0)
                {
                    var classDetails = classDeclarationSyntax.GetClassDetails();
                    var classHashes  = Generator.Get(classDetails.Attribute, classDetails.AttributeArgument).Select(generator =>
                        {
                            var key   = generator.GetEnumeratedType();
                            var value = generator.AddClass(classDetails, previousNodeDetails.ParentHashes == null ? string.Empty : previousNodeDetails.ParentHashes[key]);
                            return(new KeyValuePair <XChains, string>(key, value));
                        }).ToDictionary(x => x.Key, x => x.Value);

                    if (classDetails.IsModel)
                    {
                        Models.Add(classDetails.Name, new List <ModelProperty>());
                    }

                    classDetails.ParentHashes = classHashes;

                    var singleLineComments = classDeclarationSyntax.DescendantTrivia().Where(descendent => descendent.IsKind(SyntaxKind.SingleLineCommentTrivia));
                    foreach (var singleLineComment in singleLineComments)
                    {
                        var comment = singleLineComment.ToFullString().Split("//").Last().Trim();
                        if (Regex.IsMatch(syntaxNode.ToString(), Constants.XOnRegex) && classHashes.ContainsKey(XChains.Ethereum))
                        {
                            var expressionDetails = singleLineComment.GetExpressionDetails();
                            Generator.Get(Constants.XOn, Constants.XOnEthereumChain).ForEach(generator =>
                                {
                                    generator.AddExpression(expressionDetails, classHashes.Where(classHash => classHash.Key == XChains.Ethereum).FirstOrDefault().Value);
                                });
                        }
                    }

                    foreach (var member in classDeclarationSyntax.Members)
                    {
                        ProcessChild(member, classDetails);
                    }
                }
            }

            break;

            case SyntaxKind.FieldDeclaration:
            {
                FieldDeclarationSyntax fieldDeclarationSyntax = (FieldDeclarationSyntax)syntaxNode;

                if (previousNodeDetails != null && previousNodeDetails.GetType() == typeof(ClassDetails))
                {
                    var fieldDetails = fieldDeclarationSyntax.GetFieldDetails();
                    if (fieldDetails.Attribute.Equals(string.Empty))
                    {
                        fieldDetails.Attribute         = previousNodeDetails.Attribute;
                        fieldDetails.AttributeArgument = previousNodeDetails.AttributeArgument;
                    }

                    var fieldHashes = Generator.Get(fieldDetails.Attribute, fieldDetails.AttributeArgument).Select(generator =>
                        {
                            var key   = generator.GetEnumeratedType();
                            var value = generator.AddField(fieldDetails, previousNodeDetails.ParentHashes == null ? string.Empty : previousNodeDetails.ParentHashes[key]);
                            return(new KeyValuePair <XChains, string>(key, value));
                        }).ToDictionary(x => x.Key, x => x.Value);

                    var parsedPreviousNodeDetails = (ClassDetails)previousNodeDetails;
                    if (parsedPreviousNodeDetails.IsModel)
                    {
                        foreach (var fieldHash in fieldHashes)
                        {
                            Models[parsedPreviousNodeDetails.Name].Add(new ModelProperty
                                {
                                    Location    = fieldHash.Key,
                                    Hash        = fieldHash.Value,
                                    IsParameter = fieldDetails.IsParameter
                                });
                        }
                    }
                }
                else
                {
                    throw new InvalidExpressionException("Field declared in incorrect place...");
                }
            }

            break;

            case SyntaxKind.ConstructorDeclaration:
            {
                ConstructorDeclarationSyntax constructorDeclarationSyntax = (ConstructorDeclarationSyntax)syntaxNode;

                if (previousNodeDetails != null && previousNodeDetails.GetType() == typeof(ClassDetails))
                {
                    var constructorDetails = constructorDeclarationSyntax.GetConstructorDetails();
                    if (constructorDetails.Attribute.Equals(string.Empty))
                    {
                        constructorDetails.Attribute         = previousNodeDetails.Attribute;
                        constructorDetails.AttributeArgument = previousNodeDetails.AttributeArgument;
                    }

                    var constructorHashes = Generator.Get(constructorDetails.Attribute, constructorDetails.AttributeArgument).Select(generator =>
                        {
                            var key   = generator.GetEnumeratedType();
                            var value = generator.AddConstructor(constructorDetails, previousNodeDetails.ParentHashes == null ? string.Empty : previousNodeDetails.ParentHashes[key]);
                            return(new KeyValuePair <XChains, string>(key, value));
                        }).ToDictionary(x => x.Key, x => x.Value);

                    var    statementQueue     = new Queue <SyntaxNode>(constructorDeclarationSyntax.Body.Statements);
                    string lastKnownBlockHash = string.Empty;

                    while (statementQueue.Count > 0)
                    {
                        var member = statementQueue.Dequeue();
                        if (Regex.IsMatch(member.ToString(), Constants.XOnRegex) && statementQueue.Peek().Kind() == SyntaxKind.Block)
                        {
                            var onChainArguments = member.ToString().Split('(', ')')[1].Split(',').ToList();
                            var blockAttribute   = onChainArguments.First().Contains("\"") ? onChainArguments.First().Replace("\"", "") : onChainArguments.First();
                            var argumentList     = onChainArguments.Skip(1).ToList().Select(argument => argument.Trim()).ToList();

                            constructorDetails.Arguments = argumentList;

                            constructorDetails.ParentHashes      = constructorHashes.Where(methodHash => methodHash.Key.ToString() == blockAttribute).ToDictionary(methodHash => methodHash.Key, methodHash => methodHash.Value);
                            constructorDetails.Attribute         = Constants.XOn;
                            constructorDetails.AttributeArgument = blockAttribute;

                            Generator.Get(Constants.XOn, blockAttribute).ForEach(generator => generator.AddMethodParameters(constructorDetails, constructorHashes.Where(methodHash => methodHash.Key.ToString() == blockAttribute).First().Value, GetModelParameters, Models.Select(model => model.Key).ToList()));

                            ProcessChild(statementQueue.Dequeue(), constructorDetails);

                            lastKnownBlockHash = blockAttribute.Equals(Constants.XOnDesktop) ? constructorHashes.First().Value : string.Empty;
                        }
                        else
                        {
                            constructorDetails.ParentHashes      = constructorHashes;
                            constructorDetails.Attribute         = constructorDetails.Attribute;
                            constructorDetails.AttributeArgument = constructorDetails.AttributeArgument;
                            ProcessChild(member, constructorDetails);
                        }
                    }
                }
                else
                {
                    throw new InvalidExpressionException("Constructor declared in incorrect place...");
                }
            }

            break;

            case SyntaxKind.MethodDeclaration:
            {
                MethodDeclarationSyntax methodDeclarationSyntax = (MethodDeclarationSyntax)syntaxNode;

                if (previousNodeDetails != null && previousNodeDetails.GetType() == typeof(ClassDetails))
                {
                    var methodDetails = methodDeclarationSyntax.GetMethodDetails();
                    if (methodDetails.Attribute.Equals(string.Empty))
                    {
                        methodDetails.Attribute         = previousNodeDetails.Attribute;
                        methodDetails.AttributeArgument = previousNodeDetails.AttributeArgument;
                    }

                    var methodHashes = Generator.Get(string.IsNullOrEmpty(methodDetails.Attribute) ? previousNodeDetails.Attribute : methodDetails.Attribute, string.IsNullOrEmpty(methodDetails.Attribute) ? previousNodeDetails.AttributeArgument : methodDetails.AttributeArgument).Select(generator =>
                        {
                            var key   = generator.GetEnumeratedType();
                            var value = generator.AddMethod(methodDetails, previousNodeDetails.ParentHashes == null ? string.Empty : previousNodeDetails.ParentHashes[key]);
                            return(new KeyValuePair <XChains, string>(key, value));
                        }).ToDictionary(x => x.Key, x => x.Value);

                    var    statementQueue     = new Queue <SyntaxNode>(methodDeclarationSyntax.Body.Statements);
                    string lastKnownBlockHash = string.Empty;

                    while (statementQueue.Count > 0)
                    {
                        var member = statementQueue.Dequeue();
                        if (Regex.IsMatch(member.ToString(), Constants.XOnRegex) && statementQueue.Peek().Kind() == SyntaxKind.Block)
                        {
                            var onChainArguments = member.ToString().Split('(', ')')[1].Split(',').ToList();
                            var blockAttribute   = onChainArguments.First().Contains("\"") ? onChainArguments.First().Replace("\"", "") : onChainArguments.First();
                            var argumentList     = onChainArguments.Skip(1).ToList().Select(argument => argument.Trim()).ToList();
                            var isSynchronous    = member.ToString().StartsWith(Constants.SynchronousEscapeCharacter);

                            methodDetails.Arguments = argumentList;

                            methodDetails.IsSynchronous     = isSynchronous;
                            methodDetails.ParentHashes      = methodHashes.Where(methodHash => methodHash.Key.ToString() == blockAttribute).ToDictionary(methodHash => methodHash.Key, methodHash => methodHash.Value);
                            methodDetails.Attribute         = Constants.XOn;
                            methodDetails.AttributeArgument = blockAttribute;

                            Generator.Get(Constants.XOn, blockAttribute).ForEach(generator =>
                                {
                                    var xCallArguments = generator.AddMethodParameters(methodDetails, methodHashes.Where(methodHash => methodHash.Key.ToString() == blockAttribute).First().Value, GetModelParameters, Models.Select(model => model.Key).ToList());
                                    generator.AddMethodReturnTypes(methodDetails, methodHashes.Where(methodHash => methodHash.Key.ToString() == blockAttribute).First().Value, GetModelReturnsTypes, Models.Select(model => model.Key).ToList());

                                    if (!blockAttribute.Equals(Constants.XOnDesktop))
                                    {
                                        Generator.Get(Constants.XOn, Constants.XOnDesktop).ForEach(generator =>
                                        {
                                            var isReturnStatement = member.ToString().StartsWith("return");
                                            generator.AddExpression(new ExpressionDetails()
                                            {
                                                Statement = (isReturnStatement ? "return " : string.Empty) + (methodDetails.IsSynchronous ? "await " : string.Empty) + string.Format(Constants.XCallExpression, Constants.XOnEthereumChain, methodDetails.Identifier, xCallArguments)
                                            }, lastKnownBlockHash);
                                        });
                                    }
                                });


                            ProcessChild(statementQueue.Dequeue(), methodDetails);

                            lastKnownBlockHash = blockAttribute.Equals(Constants.XOnDesktop) ? methodHashes.First().Value : string.Empty;
                        }
                        else
                        {
                            methodDetails.ParentHashes      = methodHashes;
                            methodDetails.Attribute         = methodDetails.Attribute;
                            methodDetails.AttributeArgument = methodDetails.AttributeArgument;
                            ProcessChild(member, methodDetails);
                        }
                    }
                }
                else
                {
                    throw new InvalidExpressionException("Method declared in incorrect place...");
                }
            }

            break;

            case SyntaxKind.SingleLineCommentTrivia:
            case SyntaxKind.IfStatement:
            case SyntaxKind.ReturnStatement:
            case SyntaxKind.ExpressionStatement:
            case SyntaxKind.LocalDeclarationStatement:
            {
                if (previousNodeDetails != null)
                {
                    var expressionDetails = syntaxNode.GetExpressionDetails();
                    var statementHashes   = Generator.Get(previousNodeDetails.Attribute, previousNodeDetails.AttributeArgument).Select(generator =>
                        {
                            var key   = generator.GetEnumeratedType();
                            var value = generator.AddExpression(expressionDetails, previousNodeDetails.ParentHashes == null ? string.Empty : previousNodeDetails.ParentHashes[key], Models.Select(model => model.Key).ToList());
                            return(new KeyValuePair <XChains, string>(key, value));
                        }).ToDictionary(x => x.Key, x => x.Value);
                }
                else
                {
                    throw new InvalidExpressionException("Expression declared in incorrect place...");
                }
            }

            break;

            case SyntaxKind.Block:
            {
                BlockSyntax blockSyntax = (BlockSyntax)syntaxNode;

                if (previousNodeDetails != null)
                {
                    foreach (var child in blockSyntax.ChildNodes())
                    {
                        ProcessChild(child, previousNodeDetails);
                    }
                }
                else
                {
                    throw new InvalidExpressionException("Block declared in incorrect place...");
                }

                break;
            }

            default:
            {
                foreach (var member in syntaxNode.ChildNodes())
                {
                    ProcessChild(member, new NodeDetails());
                }

                break;
            }
            }
        }
예제 #8
0
        private void HandleStatementSyntax(StatementSyntax statementSyntax)
        {
            BlockSyntax blockSyntax = statementSyntax as BlockSyntax;

            if (blockSyntax != null)
            {
                _output.HandleLeadingTrivia(blockSyntax);

                HandleTokenAndTrivia(blockSyntax.OpenBraceToken);

                foreach (StatementSyntax childStatementSyntax in blockSyntax.ChildNodes())
                {
                    HandleStatementSyntax(childStatementSyntax);
                }

                HandleTokenAndTrivia(blockSyntax.CloseBraceToken);

                _output.HandleTrailingTrivia(blockSyntax);
                return;
            }

            ExpressionStatementSyntax expressionStatementSyntax = statementSyntax as ExpressionStatementSyntax;

            if (expressionStatementSyntax != null)
            {
                ParseExpressionStatementDeclaration(expressionStatementSyntax);
                return;
            }

            IfStatementSyntax ifStatementSyntax = statementSyntax as IfStatementSyntax;

            if (ifStatementSyntax != null)
            {
                _output.HandleLeadingTrivia(statementSyntax);

                ParseOperatorToken(ifStatementSyntax.IfKeyword);
                ParseOperatorToken(ifStatementSyntax.OpenParenToken);
                _expression.ParseExpressionSyntax(ifStatementSyntax.Condition);
                ParseOperatorToken(ifStatementSyntax.CloseParenToken);

                HandleStatementSyntax(ifStatementSyntax.Statement);

                if (ifStatementSyntax.Else != null)
                {
                    _output.HandleLeadingTrivia(ifStatementSyntax.Else);

                    _output.Add(ifStatementSyntax.Else.ElseKeyword.ValueText);
                    HandleStatementSyntax(ifStatementSyntax.Else.Statement);

                    _output.HandleTrailingTrivia(ifStatementSyntax.Else);
                }

                _output.HandleTrailingTrivia(statementSyntax);
                return;
            }

            LocalDeclarationStatementSyntax localDeclarationStatementSyntax = statementSyntax as LocalDeclarationStatementSyntax;

            if (localDeclarationStatementSyntax != null)
            {
                _output.HandleLeadingTrivia(localDeclarationStatementSyntax);

                _output.HandleLeadingTrivia(localDeclarationStatementSyntax.Declaration.Type);
                _output.Add(localDeclarationStatementSyntax.Declaration.Type.ToString());
                _output.HandleTrailingTrivia(localDeclarationStatementSyntax.Declaration.Type);

                foreach (var variable in localDeclarationStatementSyntax.Declaration.Variables)
                {
                    HandleTokenAndTrivia(variable.Identifier);
                    if (variable.Initializer != null)
                    {
                        HandleTokenAndTrivia(variable.Initializer.EqualsToken);
                        _expression.ParseExpressionSyntax(variable.Initializer.Value);
                    }
                }

                ParseOperatorToken(localDeclarationStatementSyntax.SemicolonToken);

                _output.HandleTrailingTrivia(localDeclarationStatementSyntax);
                return;
            }

            ForStatementSyntax forStatementSyntax = statementSyntax as ForStatementSyntax;

            if (forStatementSyntax != null)
            {
                HandleTokenAndTrivia(forStatementSyntax.ForKeyword);
                HandleTokenAndTrivia(forStatementSyntax.OpenParenToken);
                ParseTypeAndVariables(forStatementSyntax.Declaration.Type, forStatementSyntax.Declaration.Variables);

                HandleTokenAndTrivia(forStatementSyntax.FirstSemicolonToken);
                _expression.ParseExpressionSyntax(forStatementSyntax.Condition);
                HandleTokenAndTrivia(forStatementSyntax.SecondSemicolonToken);
                foreach (var incrementer in forStatementSyntax.Incrementors)
                {
                    _expression.ParseExpressionSyntax(incrementer);
                }
                HandleTokenAndTrivia(forStatementSyntax.CloseParenToken);
                HandleStatementSyntax(forStatementSyntax.Statement);
                return;
            }

            SwitchStatementSyntax switchStatementSyntax = statementSyntax as SwitchStatementSyntax;

            if (switchStatementSyntax != null)
            {
                HandleTokenAndTrivia(switchStatementSyntax.SwitchKeyword);

                HandleTokenAndTrivia(switchStatementSyntax.OpenParenToken);
                _expression.ParseExpressionSyntax(switchStatementSyntax.Expression);
                HandleTokenAndTrivia(switchStatementSyntax.CloseParenToken);

                HandleTokenAndTrivia(switchStatementSyntax.OpenBraceToken);

                foreach (SwitchSectionSyntax switchSectionSyntax in switchStatementSyntax.Sections)
                {
                    foreach (SwitchLabelSyntax switchLabelSyntax in switchSectionSyntax.Labels)
                    {
                        HandleTokenAndTrivia(switchLabelSyntax.Keyword);

                        CaseSwitchLabelSyntax caseSwitchLabelSyntax = switchLabelSyntax as CaseSwitchLabelSyntax;
                        if (caseSwitchLabelSyntax != null)
                        {
                            _expression.ParseExpressionSyntax(caseSwitchLabelSyntax.Value);
                        }

                        HandleTokenAndTrivia(switchLabelSyntax.ColonToken);
                    }

                    foreach (StatementSyntax childStatementSyntax in switchSectionSyntax.Statements)
                    {
                        HandleStatementSyntax(childStatementSyntax);
                    }
                }

                HandleTokenAndTrivia(switchStatementSyntax.CloseBraceToken);

                return;
            }

            BreakStatementSyntax breakStatementSyntax = statementSyntax as BreakStatementSyntax;

            if (breakStatementSyntax != null)
            {
                HandleTokenAndTrivia(breakStatementSyntax.BreakKeyword);
                HandleTokenAndTrivia(breakStatementSyntax.SemicolonToken);
                return;
            }

            int k = 12;
        }
예제 #9
0
        private void AddBlockChildNodes(BlockSyntax node, string memberName)
        {
            CSharpBlock codeBlock = null;

            foreach (var blockChildNode in node.ChildNodes())
            {
                if (blockChildNode.HasLeadingTrivia)
                {
                    var trivia = blockChildNode.GetLeadingTrivia();

                    // inside method multiline comment
                    AddMultiLineDocumentationComment(trivia, () =>
                    {
                        // flush what we may have collected so far
                        if (codeBlock != null)
                        {
                            Blocks.Add(codeBlock);
                            codeBlock = null;
                        }
                    });

                    if (blockChildNode.ShouldBeHidden(trivia))
                    {
                        continue;
                    }

                    if (blockChildNode.ShouldBeConvertedToJson(trivia))
                    {
                        string json;
                        if (blockChildNode.TryGetJsonForSyntaxNode(out json))
                        {
                            // flush what we may have collected so far
                            if (codeBlock != null)
                            {
                                Blocks.Add(codeBlock);
                                codeBlock = null;
                            }

                            var startingLine = blockChildNode.StartingLine();
                            Blocks.Add(new JavaScriptBlock(json, startingLine, ClassDepth, memberName));
                            continue;
                        }
                    }
                }

                if (codeBlock == null)
                {
                    codeBlock = new CSharpBlock(blockChildNode, ClassDepth, memberName);
                }
                else
                {
                    codeBlock.AddNode(blockChildNode);
                }

                if (blockChildNode.HasTrailingTrivia)
                {
                    var trivia = blockChildNode.GetTrailingTrivia();
                    AddMultiLineDocumentationComment(trivia, () =>
                    {
                        // flush what we may have collected so far
                        if (codeBlock != null)
                        {
                            Blocks.Add(codeBlock);
                            codeBlock = null;
                        }
                    });
                }
            }

            if (codeBlock != null)
            {
                Blocks.Add(codeBlock);
            }
        }
        private static bool IsValidatedNotNull(string possibleNullReference, BlockSyntax parent, SyntaxNode node,
                                               [NotNullWhen(true)] out SyntaxNode?suppressionCause)
        {
            suppressionCause = default(SyntaxNode);

            StatementSyntax?statement = node?.AncestorsAndSelf().OfType <StatementSyntax>().FirstOrDefault();
            var             siblings  = parent.ChildNodes().ToList();

            // Look in earlier statements to see if the variable was previously checked for null.
            for (int nodeIndex = siblings.FindIndex(x => x == statement); --nodeIndex >= 0;)
            {
                SyntaxNode previous = siblings[nodeIndex];

                suppressionCause = previous;
                if (previous is ExpressionStatementSyntax expressionStatement)
                {
                    if (expressionStatement.Expression is AssignmentExpressionSyntax assignmentExpression)
                    {
                        // Is the offending symbol assigned here?
                        if (InvalidatedBy(assignmentExpression.Left.ToString(), possibleNullReference))
                        {
                            return(IsKnownToBeNotNull(assignmentExpression.Right));
                        }
                    }

                    // Check if this is Assert.NotNull or Assert.IsNotNull for the same symbol
                    if (IsAssert(expressionStatement.Expression, out string member, out ArgumentListSyntax? argumentList))
                    {
                        if (member == NunitFrameworkConstants.NameOfAssertNotNull ||
                            member == NunitFrameworkConstants.NameOfAssertIsNotNull ||
                            member == NunitFrameworkConstants.NameOfAssertThat)
                        {
                            if (member == NunitFrameworkConstants.NameOfAssertThat)
                            {
                                // We must check the 2nd argument for anything but "Is.Null"
                                // E.g.: Is.Not.Null.And.Not.Empty.
                                ArgumentSyntax?secondArgument = argumentList.Arguments.ElementAtOrDefault(1);
                                if (secondArgument?.ToString() == "Is.Null")
                                {
                                    continue;
                                }
                            }

                            ArgumentSyntax firstArgument = argumentList.Arguments.First();
                            if (CoveredBy(firstArgument.Expression.ToString(), possibleNullReference))
                            {
                                return(true);
                            }
                        }
                    }
                }
                else if (previous is LocalDeclarationStatementSyntax localDeclarationStatement)
                {
                    VariableDeclarationSyntax declaration = localDeclarationStatement.Declaration;
                    foreach (var variable in declaration.Variables)
                    {
                        if (variable.Identifier.ToString() == possibleNullReference)
                        {
                            return(IsKnownToBeNotNull(variable.Initializer?.Value));
                        }
                    }
                }
            }

            return(false);
        }
예제 #11
0
        public void VisitBlock(BlockSyntax node)
        {
            if (node == null)
                throw new ArgumentNullException("node");

            node.Validate();

            WriteLeadingTrivia(node);

            bool writeNewlineBefore = !(
                node.Parent is BlockSyntax ||
                node.Parent is LabeledStatementSyntax
            );

            if (!node.ChildNodes().Any())
            {
                _writer.EmptyBlock(writeNewlineBefore);
            }
            else
            {
                _writer.BeginBlock(writeNewlineBefore, true);

                _writer.PushBraceFormatting(_writer.Configuration.BracesLayout.Other);

                foreach (var statement in node.Statements)
                {
                    statement.Accept(this);
                }

                _writer.PopBraceFormatting();

                _writer.EndBlock();
            }

            WriteTrailingTrivia(node);
        }
예제 #12
0
            public override void VisitBlock(BlockSyntax node)
            {
                var statements  = node.ChildNodes().OfType <ExpressionStatementSyntax>();
                var invocations = statements.Select(s => s.Expression).OfType <InvocationExpressionSyntax>();
                var glOperators = invocations.Select(i => i.Expression).OfType <MemberAccessExpressionSyntax>()
                                  .Where(m => m.IsKind(SyntaxKind.SimpleMemberAccessExpression)).Where(s => s.GetFirstToken().Text == nameof(GL));
                var pushPops = glOperators.Select(g => Tuple.Create(g.Parent as InvocationExpressionSyntax, g.ChildNodes().Skip(1).First().GetFirstToken().Text))
                               .Where(p => p.Item2.StartsWith("Push") || p.Item2.StartsWith("Pop"));

                // filtering
                if (!pushPops.Any())
                {
                    base.VisitBlock(node);
                    return;
                }

                // block contains GL.Push???() or GL.Pop???
                var counters          = new int[reverseRouter.Count];        // new int[5]
                var prevPushLocations = new Location[reverseRouter.Count];   // new Location[5]

                foreach (var pair in pushPops)
                {
                    var route = router[pair.Item2];
                    if (pair.Item2.StartsWith("Push"))
                    {
                        counters[route]++;
                        if (counters[route] > 1)
                        {
                            Diagnostics.Add(Diagnostic.Create(
                                                descriptor: Rule,
                                                location: prevPushLocations[route],
                                                messageArgs: nameof(GL) + ".Pop" + reverseRouter[route]));
                            counters[router[pair.Item2]] = 1;
                        }
                        prevPushLocations[route] = pair.Item1.GetLocation();
                    }
                    else if (pair.Item2.StartsWith("Pop"))
                    {
                        counters[route]--;
                        if (counters[route] < 0)
                        {
                            Diagnostics.Add(Diagnostic.Create(
                                                descriptor: Rule,
                                                location: pair.Item1.GetLocation(),
                                                messageArgs: nameof(GL) + ".Push" + reverseRouter[route]));
                            counters[route] = 0;
                        }
                    }
                }
                for (int i = 0; i < counters.Length; i++)
                {
                    if (counters[i] > 0)
                    {
                        Diagnostics.Add(Diagnostic.Create(
                                            descriptor: Rule,
                                            location: prevPushLocations[i],
                                            messageArgs: nameof(GL) + ".Pop" + reverseRouter[i]));
                    }
                }

                base.VisitBlock(node);
            }
예제 #13
0
        public CodeRefactoring GetRefactoring(IDocument document, TextSpan textSpan, CancellationToken cancellationToken)
        {
            SyntaxNode root = (SyntaxNode)document.GetSyntaxRoot(cancellationToken);

            // If nothing selected, only cursor placed, increase the ending position by one
            if (textSpan.Length == 0)
            {
                textSpan = new TextSpan(textSpan.Start, 1);
            }

            // Get nodes for highlighted code
            IEnumerable <VariableDeclaratorSyntax> selectedNodes = root.DescendantNodes(textSpan).OfType <VariableDeclaratorSyntax>();

            // Select the node that spans the selected text most
            // Note: Here I have reversed the ranges ! node.Span.Contains, not textSpan.Contains
            VariableDeclaratorSyntax selectedNode = null;
            int bestSpan = -1;

            foreach (var node in selectedNodes)
            {
                if (node.Span.Contains(textSpan))
                {
                    int spanWidth = node.Span.Intersection(textSpan).Value.Length;
                    if (spanWidth > bestSpan)
                    {
                        bestSpan     = spanWidth;
                        selectedNode = node;
                    }
                }
            }

            if (selectedNode == null)
            {
                return(null);
            }

            VariableDeclaratorSyntax declarator = selectedNode;

            // Verify does the variable declarator has value assigned
            if (declarator.Initializer == null || declarator.HasDiagnostics)
            {
                return(null);
            }

            ISemanticModel model = document.GetSemanticModel(cancellationToken);

            ISymbol declaredSymbol = model.GetDeclaredSymbol(declarator);

            LocalDeclarationStatementSyntax declarationStatement = declarator.FirstAncestorOrSelf <LocalDeclarationStatementSyntax>();

            // Note: declarator might be within ForStatement, but cannot be inlined
            if (declarationStatement == null)
            {
                return(null);
            }

            var analysis = model.AnalyzeStatementDataFlow(declarationStatement);

            // Verify that the variable is never re-assigned
            if (analysis.WrittenOutside.Contains(declaredSymbol))
            {
                return(null);
            }

            // Variable inlineing is not allowed if variable is never used (side effects never take place then!)
            if (!analysis.ReadOutside.Contains(declaredSymbol))
            {
                return(null);
            }

            BlockSyntax block = declarationStatement.FirstAncestorOrSelf <BlockSyntax>();

            if (block == null)
            {
                return(null);
            }

            // Verify that the variables used in declaration are not re-assigned within variable usage scope
            // Consider:
            // int a = 1;
            // int b = a;
            // int c = b;
            // a = 2;
            // int d = b;
            // `b' cannot be inlined because `d' would get other value

            // Note: ChildNodes instead of DescendantNodes, because it must not be any other (nested) block
            var blockAnalysis = model.AnalyzeStatementsDataFlow(declarationStatement, block.ChildNodes().OfType <StatementSyntax>().Last());

            foreach (var initializerSymbol in model.AnalyzeExpressionDataFlow(declarator.Initializer.Value).ReadInside)
            {
                if (blockAnalysis.WrittenInside.Contains(initializerSymbol))
                {
                    return(null);
                }
            }

            return(new CodeRefactoring(
                       new[] { new InlineLocalAction(document, declarator) }
                       , declarator.Span));
        }
예제 #14
0
        public static (ISymbol symbol, BlockSyntax body, IEnumerable <SyntaxNode> expressions) GetParentMethod(this SyntaxNode node, SemanticModel model)
#endif
        {
            while (!(node is MethodDeclarationSyntax) &&
                   !(node is ConstructorDeclarationSyntax) &&
                   !(node is AccessorDeclarationSyntax) &&
                   !(node is PropertyDeclarationSyntax))
            {
                if (node == null)
                {
#if PORTABLE
                    return(new Tuple <ISymbol, BlockSyntax, IEnumerable <SyntaxNode> >(null, null, null));
#else
                    return(null, null, null);
#endif
                }
                node = node.Parent;
            }

            ISymbol     methodSymbol             = null;
            BlockSyntax body                     = null;
            IEnumerable <SyntaxNode> expressions = null;
            switch (node)
            {
            case ConstructorDeclarationSyntax ctor:
                if (ctor.Body != null)
                {
                    methodSymbol = model.GetDeclaredSymbol(ctor);
                    body         = ctor.Body;
                }
                break;

            case MethodDeclarationSyntax method:
                if (method.Body != null)
                {
                    methodSymbol = model.GetDeclaredSymbol(method);
                    body         = method.Body;
                }
                break;

            case AccessorDeclarationSyntax accessor:
                if (accessor.Body != null)
                {
                    methodSymbol = model.GetDeclaredSymbol(accessor);
                    body         = accessor.Body;
                }
                break;

            case PropertyDeclarationSyntax property:
                if (property.ExpressionBody is ArrowExpressionClauseSyntax arrowExpression)
                {
                    methodSymbol = model.GetDeclaredSymbol(property);
                    expressions  = new[] { arrowExpression.Expression };
                }
                break;
            }
            if (body != null)
            {
                expressions = body.ChildNodes();
            }

            if (methodSymbol == null || expressions == null)
            {
                // Probably a compilation error
#if PORTABLE
                return(new Tuple <ISymbol, BlockSyntax, IEnumerable <SyntaxNode> >(null, null, null));
#else
                return(null, null, null);
#endif
            }
#if PORTABLE
            return(new Tuple <ISymbol, BlockSyntax, IEnumerable <SyntaxNode> >(methodSymbol, body, expressions));
#else
            return(methodSymbol, body, expressions);
#endif
        }
예제 #15
0
        public override SyntaxNode VisitBlock(BlockSyntax node)
        {
            // Step I: rewrite loops
            var children = node.ChildNodes().OfType <StatementSyntax>().ToArray();

            for (int i = 0; i < children.Length; i++)
            {
                if (children[i].IsKind(SK.WhileStatement))
                {
                    children[i] = (StatementSyntax)VisitWhileStatement(children[i] as WhileStatementSyntax);
                }
                if (children[i].IsKind(SK.ForStatement))
                {
                    children[i] = (StatementSyntax)VisitForStatement(children[i] as ForStatementSyntax);
                }
            }

            // Step II: join child blocks - {{...}{...}{...}}
            var childrenList = new List <StatementSyntax>();

            for (int i = 0; i < children.Length; i++)
            {
                if (children[i].IsKind(SK.Block))
                {
                    childrenList.AddRange(children[i].ChildNodes().OfType <StatementSyntax>());
                }
                else
                {
                    childrenList.Add(children[i]);
                }
            }
            children = childrenList.ToArray();

            // Step III: rewrite if statements to if-else
            var index = GetIndexOfOneBeforeLastStatement(children);

            while (index != -1)
            {
                StatementSyntax newStatement       = null;
                var             oneBeforeLastChild = children[index];
                // TakeLast(children.Length - 1 - index);
                var remainingChildren = children.Skip(Math.Max(0, children.Length - (children.Length - 1 - index)));

                var oneBeforeLastChildStatements = GetStatementsFromBlock(oneBeforeLastChild.ChildNodes().OfType <StatementSyntax>());
                IEnumerable <StatementSyntax> statements;

                if (oneBeforeLastChildStatements.Count() > 0 &&
                    (oneBeforeLastChildStatements.Last().IsKind(SK.ThrowStatement) ||
                     oneBeforeLastChildStatements.Last().IsKind(SK.ReturnStatement)))
                {
                    // If last statement is a throw or return, do not append last statement
                    statements = oneBeforeLastChildStatements;
                }
                else
                {
                    var statementsList = oneBeforeLastChildStatements.ToList();
                    statementsList.AddRange(remainingChildren);
                    statements = statementsList;
                }

                if (oneBeforeLastChild.IsKind(SK.IfStatement))
                {
                    var ifStatement = (IfStatementSyntax)oneBeforeLastChild;
                    var elseChilds  = GetStatementsFromBlock(ifStatement.Else?.ChildNodes().OfType <StatementSyntax>());
                    IEnumerable <StatementSyntax> elseStatements;
                    if (elseChilds != null)
                    {
                        if (elseChilds.Count() > 0 &&
                            (elseChilds.Last().IsKind(SK.ThrowStatement) ||
                             elseChilds.Last().IsKind(SK.ReturnStatement)))
                        {
                            elseStatements = elseChilds;
                        }
                        else
                        {
                            var elseStatementsList = elseChilds.ToList();
                            elseStatementsList.AddRange(remainingChildren);
                            elseStatements = elseStatementsList;
                        }
                    }
                    else
                    {
                        elseStatements = new List <StatementSyntax>(remainingChildren);
                    }
                    var mainBlock = SF.Block(statements);
                    var elseBlock = SF.Block(elseStatements);

                    ElseClauseSyntax elseClause = elseStatements.Count() > 0 ? SF.ElseClause(elseBlock) : null;

                    newStatement = SF.IfStatement(ifStatement.Condition, mainBlock, elseClause);
                }
                else
                {
                    throw new NotImplementedException(oneBeforeLastChild.Kind().ToString());
                }

                if (newStatement != null)
                {
                    children = children.Take(index).Append(newStatement).ToArray();
                }
                else
                {
                    children = children.Take(index + 1).ToArray();
                }

                index = GetIndexOfOneBeforeLastStatement(children);
            }

            var block  = SF.Block(children);
            var result = base.VisitBlock(block);

            return(result);
        }
예제 #16
0
        static void Main(string[] args)
        {
            Console.WriteLine("Building...");

            semi = SyntaxFactory.Token(SyntaxFactory.TriviaList(), SyntaxKind.SemicolonToken, SyntaxFactory.TriviaList(SyntaxFactory.EndOfLine("\n")));

            CSharpParseOptions cSharpParseOptions = new CSharpParseOptions(LanguageVersion.CSharp1, DocumentationMode.Parse, SourceCodeKind.Script);

            tree = CSharpSyntaxTree.ParseText("", options: cSharpParseOptions) as CSharpSyntaxTree;
            root = tree.GetCompilationUnitRoot(); //(CompilationUnitSyntax)tree.GetRoot();

            //create the block and add it
            var         syntaxAnnotation = new SyntaxAnnotation("Block", "1");
            BlockSyntax block            = SyntaxFactory.Block().WithAdditionalAnnotations(syntaxAnnotation);

            currentBlock = syntaxAnnotation;

            //add block to root
            GlobalStatementSyntax globalStatement = SyntaxFactory.GlobalStatement(block);

            root = root.AddMembers(globalStatement); //root = root.WithMembers(root.Members.Add(globalStatement));

            //add to first block
            ExpressionSyntax   expressionSyntax = SyntaxFactory.IdentifierName("Print");
            ArgumentListSyntax argumentList     = SyntaxFactory.ParseArgumentList("(" + "arg1, \"literal1\"" + ")");
            //Print("// Sebastian Marsh (001790):	That’s not going to happen, Robert.");
            //
            InvocationExpressionSyntax invocationExpression = SyntaxFactory.InvocationExpression(expressionSyntax, argumentList);
            ExpressionStatementSyntax  expressionStatement  = SyntaxFactory.ExpressionStatement(invocationExpression, semi);

            AddToCurrentBlock(expressionStatement);

            //add a block to the block
            syntaxAnnotation = new SyntaxAnnotation("Block", "2");
            BlockSyntax newBlock = SyntaxFactory.Block().WithAdditionalAnnotations(syntaxAnnotation);

            AddToCurrentBlock(newBlock);
            currentBlock = syntaxAnnotation;


            var variableIdentifier = SyntaxFactory.IdentifierName("vVar");
            //var variableExpression = GetVariableExpression(assignValue);
            int value = int.Parse("1");
            var variableExpression = SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(value));

            var binaryExpression = SyntaxFactory.BinaryExpression(SyntaxKind.AddExpression, variableIdentifier, variableExpression);

            //AssignmentExpressionSyntax assignment = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, variableIdentifier, variableExpression);
            AssignmentExpressionSyntax assignment = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, variableIdentifier, binaryExpression);

            expressionStatement = SyntaxFactory.ExpressionStatement(assignment, semi);

            //add to the current block
            AddToCurrentBlock(expressionStatement);

            //move back a block
            GetPreviousBlock();

            var variable = GetVariable();

            SyntaxToken insertAfter     = block.GetFirstToken();
            SyntaxNode  insertAfterNode = null;

            BlockSyntax theBlock = GetCurrentBlock();

            foreach (var token in theBlock.DescendantTokens().Where(n => n.ValueText == "literal1"))
            {
                insertAfter     = FindNextSemi(token);
                insertAfterNode = insertAfter.Parent;
            }

            VariableDeclaratorSyntax        declarator          = SyntaxFactory.VariableDeclarator(identifier: SyntaxFactory.Identifier("var12"));
            VariableDeclarationSyntax       variableDeclaration = SyntaxFactory.VariableDeclaration(type: SyntaxFactory.ParseTypeName("String "), variables: SyntaxFactory.SeparatedList <VariableDeclaratorSyntax>().Add(declarator));
            SyntaxTokenList                 modifiers           = new SyntaxTokenList();
            LocalDeclarationStatementSyntax localDeclaration    = SyntaxFactory.LocalDeclarationStatement(modifiers, variableDeclaration, semi);
            BlockSyntax addBlock = SyntaxFactory.Block(localDeclaration);

            root = root.InsertNodesAfter(insertAfterNode, addBlock.ChildNodes());

            //show source
            //block = root.DescendantNodes().OfType<BlockSyntax>().Where(n => n.HasAnnotation(currentBlock)).Single();
            //Console.WriteLine("block source:");
            //Console.WriteLine(block.GetText());
            Console.WriteLine("root source:");
            Console.WriteLine(root.GetText());
            Console.WriteLine("Complete.");
            Console.ReadLine();
        }
        private static bool IsValidatedNotNullByPreviousStatementInSameBlock(string possibleNullReference, BlockSyntax parent, StatementSyntax statement)
        {
            var siblings = parent.ChildNodes().ToList();

            // Look in earlier statements to see if the variable was previously checked for null.
            for (int nodeIndex = siblings.FindIndex(x => x == statement); --nodeIndex >= 0;)
            {
                SyntaxNode previous = siblings[nodeIndex];

                if (previous is ExpressionStatementSyntax expressionStatement)
                {
                    if (expressionStatement.Expression is AssignmentExpressionSyntax assignmentExpression)
                    {
                        // Is the offending symbol assigned here?
                        if (InvalidatedBy(assignmentExpression.Left.ToString(), possibleNullReference))
                        {
                            return(IsKnownToBeNotNull(assignmentExpression.Right));
                        }
                    }

                    // Check if this is an Assert for the same symbol
                    if (AssertHelper.IsAssert(expressionStatement.Expression, out string member, out ArgumentListSyntax? argumentList))
                    {
                        string firstArgument = argumentList.Arguments.First().Expression.ToString();

                        if (member == NUnitFrameworkConstants.NameOfAssertThat)
                        {
                            string?secondArgument =
                                argumentList.Arguments.ElementAtOrDefault(1)?.Expression.ToString();

                            // If test is on <nullable>.HasValue
                            if (IsHasValue(firstArgument, possibleNullReference))
                            {
                                // Could be:
                                // Assert.That(<nullable>.HasValue)
                                // Assert.That(<nullable>.HasValue, "Ensure Value Set")
                                // Assert.That(<nullable>.HasValue, Is.True)
                                if (secondArgument != "Is.False")
                                {
                                    return(true);
                                }
                            }
                            else
                            {
                                // Null check, could be Is.Not.Null or more complex
                                // like Is.Not.Null.And.Not.Empty.
                                if (secondArgument != "Is.Null")
                                {
                                    if (CoveredBy(firstArgument, possibleNullReference))
                                    {
                                        return(true);
                                    }
                                }
                            }
                        }
                        else if (member == NUnitFrameworkConstants.NameOfAssertNotNull ||
                                 member == NUnitFrameworkConstants.NameOfAssertIsNotNull)
                        {
                            if (CoveredBy(firstArgument, possibleNullReference))
                            {
                                return(true);
                            }
                        }
                        else if (member == NUnitFrameworkConstants.NameOfAssertIsTrue ||
                                 member == NUnitFrameworkConstants.NameOfAssertTrue)
                        {
                            if (IsHasValue(firstArgument, possibleNullReference))
                            {
                                return(true);
                            }
                        }
                    }
                }
                else if (previous is LocalDeclarationStatementSyntax localDeclarationStatement)
                {
                    VariableDeclarationSyntax declaration = localDeclarationStatement.Declaration;
                    foreach (var variable in declaration.Variables)
                    {
                        if (variable.Identifier.ToString() == possibleNullReference)
                        {
                            return(IsKnownToBeNotNull(variable.Initializer?.Value));
                        }
                    }
                }
            }

            return(false);
        }
예제 #18
0
        /* Method that checks whether or not Singleton class is thread safe
         * by way of double check locking
         */
        public bool IsDoubleCheckLocked(ClassDeclarationSyntax classDec)
        {
            /* List of methods that might be used to
             * return instances of singleton class
             */
            List <MethodDeclarationSyntax> possibleInstanceMethods =
                new List <MethodDeclarationSyntax>();

            // Get List of all methodDeclarations in class
            List <MethodDeclarationSyntax> methodDeclarations =
                classDec.DescendantNodes().
                OfType <MethodDeclarationSyntax>().ToList();

            bool classContainsValidMethod = false;

            foreach (MethodDeclarationSyntax methodDec in methodDeclarations)
            {
                bool isPublic = false;
                bool isStatic = false;

                /* Check if method returns an instance of class first,
                 * otherwise don't do more taxing operations
                 */
                if (methodDec.ReturnType.ToString().
                    Equals(classDec.Identifier.Text))
                {
                    /* Check whether or not method is public and static,
                     * both of which instance method should be
                     */

                    SyntaxTokenList modifiers = methodDec.Modifiers;
                    foreach (SyntaxToken modifier in modifiers)
                    {
                        if (modifier.IsKind(SyntaxKind.PublicKeyword))
                        {
                            isPublic = true;
                        }
                        else if (modifier.IsKind(SyntaxKind.StaticKeyword))
                        {
                            isStatic = true;
                        }
                    }
                }

                /* isPublic and isStatic can only have been changed to true
                 * if returnType is correct. If conditions are fulfilled,
                 * add checked method to list of possible instance methods
                 */
                if (isPublic && isStatic)
                {
                    possibleInstanceMethods.Add(methodDec);
                }
            }

            foreach (
                MethodDeclarationSyntax methodDec in
                possibleInstanceMethods)
            {
                /* Can choose .First() because method can
                 * syntactically only have one Block
                 */
                BlockSyntax block = methodDec.ChildNodes().
                                    OfType <BlockSyntax>().First();

                string            identifier         = "";
                bool              containsFirstCheck = false;
                List <SyntaxNode> nodes =
                    block.ChildNodes().OfType <SyntaxNode>().ToList();

                BlockSyntax secondBlock = null;
                foreach (SyntaxNode node in nodes)
                {
                    /* Check whether or not the block contains an if-stmt
                     * that checks the instance variable for null
                     */
                    if (node.IsKind(SyntaxKind.IfStatement))
                    {
                        List <SyntaxNodeOrToken> subNodes =
                            node.ChildNodesAndTokens().
                            OfType <SyntaxNodeOrToken>().ToList();

                        bool isEqualsEquals = false;
                        bool checksForNull  = false;

                        foreach (SyntaxNodeOrToken subNode in subNodes)
                        {
                            if (subNode.IsKind(SyntaxKind.EqualsExpression))
                            {
                                List <SyntaxNodeOrToken> subSubNodes =
                                    subNode.ChildNodesAndTokens().
                                    OfType <SyntaxNodeOrToken>().ToList();

                                foreach (
                                    SyntaxNodeOrToken subSubNode in
                                    subSubNodes)
                                {
                                    if (subSubNode.IsKind(
                                            SyntaxKind.IdentifierName))
                                    {
                                        identifier = subSubNode.ToString();
                                    }
                                    else if (subSubNode.IsKind(
                                                 SyntaxKind.EqualsEqualsToken))
                                    {
                                        isEqualsEquals = true;
                                    }
                                    else if (subSubNode.IsKind(
                                                 SyntaxKind.NullLiteralExpression))
                                    {
                                        checksForNull = true;
                                    }
                                }
                            }
                        }

                        if (isEqualsEquals && checksForNull)
                        {
                            containsFirstCheck = true;
                            secondBlock        = node.ChildNodes().
                                                 OfType <BlockSyntax>().First();
                        }
                    }
                }

                bool        containsLock = false;
                BlockSyntax thirdBlock   = null;

                /* If instance variable is checked for null first,
                 * check if after that check, a lock occurs
                 */
                if (containsFirstCheck)
                {
                    List <SyntaxNode> subNodes =
                        secondBlock.ChildNodes().OfType <SyntaxNode>().ToList();

                    foreach (SyntaxNode subNode in subNodes)
                    {
                        if (subNode.IsKind(SyntaxKind.LockStatement))
                        {
                            containsLock = true;
                            thirdBlock   = subNode.ChildNodes().
                                           OfType <BlockSyntax>().First();
                        }
                    }
                }

                bool        containsSecondCheck = false;
                BlockSyntax fourthBlock         = null;

                /* If the lock occurs, check if another
                 * null-check on instance variable happens
                 */
                if (containsLock)
                {
                    List <SyntaxNode> subNodes =
                        thirdBlock.ChildNodes().
                        OfType <SyntaxNode>().ToList();

                    foreach (SyntaxNode subNode in subNodes)
                    {
                        if (subNode.IsKind(
                                SyntaxKind.IfStatement))
                        {
                            List <SyntaxNode> subSubNodes =
                                subNode.ChildNodes().
                                OfType <SyntaxNode>().ToList();

                            foreach (SyntaxNode subSubNode in subSubNodes)
                            {
                                if (subSubNode.IsKind(
                                        SyntaxKind.EqualsExpression))
                                {
                                    List <SyntaxNodeOrToken> subSubSubNodes =
                                        subSubNode.ChildNodesAndTokens().
                                        OfType <SyntaxNodeOrToken>().ToList();


                                    bool correctIdentifier = false;
                                    bool isEqualsEquals    = false;
                                    bool checksForNull     = false;

                                    foreach (
                                        SyntaxNodeOrToken subSubSubNode in
                                        subSubSubNodes)
                                    {
                                        if (subSubSubNode.IsKind(
                                                SyntaxKind.IdentifierName) &&
                                            subSubSubNode.ToString() ==
                                            identifier)
                                        {
                                            correctIdentifier = true;
                                        }
                                        else if (subSubSubNode.IsKind(
                                                     SyntaxKind.EqualsEqualsToken))
                                        {
                                            isEqualsEquals = true;
                                        }
                                        else if (subSubSubNode.IsKind(
                                                     SyntaxKind.NullLiteralExpression))
                                        {
                                            checksForNull = true;
                                        }
                                    }

                                    if (correctIdentifier &&
                                        isEqualsEquals &&
                                        checksForNull)
                                    {
                                        containsSecondCheck = true;
                                        fourthBlock         = subNode.ChildNodes().
                                                              OfType <BlockSyntax>().First();
                                    }
                                }
                            }
                        }
                    }
                }

                bool isValidDoubleCheck = false;

                /* If second null-check happens, finally check whether or not
                 * after that second null-check, a value is assigned to
                 * the instance variable of type {ClassName}
                 * in which case it can be determined that a valid
                 * double check lock has occured
                 */
                if (containsSecondCheck)
                {
                    List <SyntaxNode> subNodes =
                        fourthBlock.ChildNodes().
                        OfType <SyntaxNode>().ToList();

                    foreach (SyntaxNode subNode in subNodes)
                    {
                        if (subNode.IsKind(SyntaxKind.ExpressionStatement))
                        {
                            List <SyntaxNode> subSubNodes =
                                subNode.ChildNodes().
                                OfType <SyntaxNode>().ToList();

                            foreach (SyntaxNode subSubNode in subSubNodes)
                            {
                                if (subSubNode.IsKind
                                        (SyntaxKind.SimpleAssignmentExpression))
                                {
                                    /* SimpleAssignmentExpression can
                                     * only have an identifier name
                                     */
                                    if (subSubNode.ChildNodes().
                                        OfType <IdentifierNameSyntax>().
                                        First().Identifier.Text == identifier)
                                    {
                                        /* Only one ObjectCreationExpression
                                         * can be attached to a
                                         * SimpleAssignmentExpression
                                         */
                                        ObjectCreationExpressionSyntax
                                                objectCreationExp =
                                            subSubNode.ChildNodes().
                                            OfType <ObjectCreationExpressionSyntax>().
                                            First();

                                        /* ObjectCreationExpression can only
                                         * have one IdentifierName
                                         * attached to it
                                         */
                                        if (objectCreationExp.ChildNodes().
                                            OfType <IdentifierNameSyntax>().
                                            First().Identifier.Text ==
                                            classDec.Identifier.Text)
                                        {
                                            isValidDoubleCheck = true;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (isValidDoubleCheck)
                    {
                        classContainsValidMethod = true;
                    }
                }
            }

            return(classContainsValidMethod);
        }
 // doesn't include variables declared in declaration expressions
 private static void GetLocalNames(BlockSyntax block, ref List<SyntaxToken> result)
 {
     foreach (var child in block.ChildNodes())
     {
         if (child.IsKind(SyntaxKind.LocalDeclarationStatement))
         {
             GetLocalNames(((LocalDeclarationStatementSyntax)child).Declaration, ref result);
         }
     }
 }
예제 #20
0
        public BlockSyntax AddVariablesToBlock(BlockSyntax block)
        {
            //block = block.
            int totalVariables  = Variables.Count;
            int currentVariable = 0;

            //SyntaxToken insertAfter = block.GetFirstToken();
            SyntaxNode insertNode      = null;
            bool       insertIsAfter   = true;
            int        insertSpanStart = 0;

            foreach (var variable in Variables.OrderBy(n => n.Key))
            {
                currentVariable++;
                if (currentVariable < 3)
                {
                    continue;
                }

                if (variable.Value.Static &&
                    variable.Value.Used == true)
                {
                    if (variable.Value.Used == false)
                    {
                        Console.WriteLine();
                    }
                    //SyntaxToken firstToken = block.DescendantTokens().Where(n => n.HasAnnotation(new SyntaxAnnotation("StaticVar", variable.Key.ToString()))).Single();
                    //find the static value
                    object staticValue = GetCurrentValue(variable.Key);

                    //SyntaxKind literalKind;
                    //if (staticValue is string)
                    //{
                    //    staticValue = "\"" + (string)staticValue + "\"";
                    //}

                    //foreach (var node in block.DescendantNodes().OfType<LiteralExpressionSyntax>().Where(n => n.GetText().ToString() == staticValue.ToString()))
                    //{
                    //    Console.WriteLine();
                    //    //insertAfter = node.DescendantNodes().Where(n => n.Kind() == SyntaxKind.SemicolonToken).First();
                    //    break;
                    //}

                    //SyntaxNode fromNode = null;
                    //if (insertAfterNode == null)
                    //{
                    //    fromNode = block;
                    //}
                    //else
                    //{
                    //    fromNode = insertAfterNode;
                    //}

                    //foreach (var token in block.DescendantTokens().Where(n => n.ValueText == staticValue.ToString()).Where(o => o.SpanStart > insertSpanStart).First())
                    //{
                    var tokens = block.DescendantTokens().Where(n => n.ValueText == staticValue.ToString() && n.SpanStart > insertSpanStart);
                    if (tokens.Count() > 0)
                    {
                        var         token       = tokens.First();
                        SyntaxToken insertToken = FindNextSemi(token);
                        if (insertToken.Kind() == SyntaxKind.SemicolonToken)
                        {
                            insertNode    = insertToken.Parent;
                            insertIsAfter = true;
                        }
                        else
                        {
                            if (insertToken.Parent.ChildNodes().Count() > 0)
                            {
                                insertNode    = insertToken.Parent.ChildNodes().First();
                                insertIsAfter = false;
                            }
                            else
                            {
                                insertNode    = insertToken.Parent;
                                insertIsAfter = true;
                            }
                        }
                        insertSpanStart = token.SpanStart;
                        //    break;
                        //}
                    }
                }
                else
                {
                    //SyntaxTokenList newTokens = new SyntaxTokenList();
                    //newTokens = newTokens.Add(insertAfter);
                    LocalDeclarationStatementSyntax localDeclarationStatementSyntax = GetVariableDeclaration(variable.Value);
                    //newTokens.Add(variableToken.DescendantNodesAndTokensAndSelf);
                    //block = block.ReplaceToken(insertAfter, insertAfter);
                    //StatementSyntax statementSyntax = localDeclarationStatementSyntax as StatementSyntax;
                    //var varNode = SyntaxFactory.("\"valid regex\"");
                    //SyntaxAnnotation syntaxAnnotation = new SyntaxAnnotation("Variable", variable.Key.ToString());

                    BlockSyntax addBlock = SyntaxFactory.Block(localDeclarationStatementSyntax); //.WithAdditionalAnnotations(syntaxAnnotation);

                    if (insertNode == null)
                    {
                        block = block.InsertNodesBefore(block.ChildNodes().First(), addBlock.ChildNodes());
                    }
                    else
                    {
                        if (insertIsAfter)
                        {
                            block = block.InsertNodesAfter(insertNode, addBlock.ChildNodes());
                        }
                        else
                        {
                            block = block.InsertNodesBefore(insertNode, addBlock.ChildNodes());
                        }
                    }

                    //insertAfterNode = block.DescendantNodes().OfType<LocalDeclarationStatementSyntax>().Where(n => n.HasAnnotation(syntaxAnnotation)).Single();
                    insertNode      = block.DescendantNodes().OfType <LocalDeclarationStatementSyntax>().Last();
                    insertSpanStart = insertNode.SpanStart;
                    insertIsAfter   = true;
                }
            }
            return(block);
        }