コード例 #1
0
            private void AddPrecedingRelevantExpressions()
            {
                // If we're not the first statement in this block, 
                // and there's an expression or declaration statement directly above us,
                // then add the expressions from that as well.

                StatementSyntax previousStatement;

                var block = _parentStatement as BlockSyntax;
                if (block != null &&
                    block.CloseBraceToken == _token)
                {
                    // If we're at the last brace of a block, use the last
                    // statement in the block.
                    previousStatement = block.Statements.LastOrDefault();
                }
                else
                {
                    previousStatement = _parentStatement.GetPreviousStatement();
                }

                if (previousStatement != null)
                {
                    switch (previousStatement.Kind())
                    {
                        case SyntaxKind.ExpressionStatement:
                        case SyntaxKind.LocalDeclarationStatement:
                            AddRelevantExpressions(previousStatement, _expressions, includeDeclarations: true);
                            break;
                        case SyntaxKind.DoStatement:
                            AddExpressionTerms((previousStatement as DoStatementSyntax).Condition, _expressions);
                            AddLastStatementOfConstruct(previousStatement);
                            break;
                        case SyntaxKind.ForStatement:
                        case SyntaxKind.ForEachStatement:
                        case SyntaxKind.IfStatement:
                        case SyntaxKind.CheckedStatement:
                        case SyntaxKind.UncheckedStatement:
                        case SyntaxKind.WhileStatement:
                        case SyntaxKind.LockStatement:
                        case SyntaxKind.SwitchStatement:
                        case SyntaxKind.TryStatement:
                        case SyntaxKind.UsingStatement:
                            AddRelevantExpressions(previousStatement, _expressions, includeDeclarations: false);
                            AddLastStatementOfConstruct(previousStatement);
                            break;
                        default:
                            break;
                    }
                }
                else
                {
                    // This is the first statement of the block. Go to the nearest enclosing statement and add its expressions
                    var statementAncestor = _parentStatement.Ancestors().OfType<StatementSyntax>().FirstOrDefault(node => !node.IsKind(SyntaxKind.Block));
                    if (statementAncestor != null)
                    {
                        AddRelevantExpressions(statementAncestor, _expressions, includeDeclarations: true);
                    }
                }
            }
コード例 #2
0
        private static void CheckStatement(SyntaxNodeAnalysisContext context, StatementSyntax statement,
                                           string executed, string execute)
        {
            if (statement.IsKind(SyntaxKind.Block))
            {
                return;
            }

            var nextStatement = context.Node.GetLastToken().GetNextToken().Parent;

            // This algorithm to get the next statement can sometimes return a parent statement (for example a BlockSyntax)
            // so we need to filter this case by returning if the nextStatement happens to be one ancestor of statement.
            if (nextStatement == null ||
                statement.Ancestors().Contains(nextStatement))
            {
                return;
            }

            var statementPosition     = statement.GetLocation().GetLineSpan().StartLinePosition;
            var nextStatementPosition = nextStatement.GetLocation().GetLineSpan().StartLinePosition;

            if (statementPosition.Character == nextStatementPosition.Character)
            {
                var lineSpan = context.Node.SyntaxTree.GetText().Lines[nextStatementPosition.Line].Span;
                var location = Location.Create(context.Node.SyntaxTree, TextSpan.FromBounds(nextStatement.SpanStart, lineSpan.End));

                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, location,
                                                                     additionalLocations: new[] { statement.GetLocation() },
                                                                     messageArgs: new object[] { executed, execute, nextStatementPosition.Line - statementPosition.Line + 1 }));
            }
        }
        public static MemberDeclarationSyntax GetContainingMember(this StatementSyntax statement)
        {
            foreach (SyntaxNode ancestor in statement.Ancestors())
            {
                switch (ancestor.Kind())
                {
                case SyntaxKind.MethodDeclaration:
                case SyntaxKind.OperatorDeclaration:
                case SyntaxKind.ConversionOperatorDeclaration:
                case SyntaxKind.ConstructorDeclaration:
                case SyntaxKind.DestructorDeclaration:
                case SyntaxKind.PropertyDeclaration:
                case SyntaxKind.EventDeclaration:
                case SyntaxKind.IndexerDeclaration:
                    return((MemberDeclarationSyntax)ancestor);

                case SyntaxKind.IncompleteMember:
                case SyntaxKind.SimpleLambdaExpression:
                case SyntaxKind.ParenthesizedLambdaExpression:
                case SyntaxKind.AnonymousMethodExpression:
                    return(null);
                }
            }

            return(null);
        }
コード例 #4
0
        private static Boolean GeneralTypeInStatementIsValid(StatementSyntax statement, SemanticModel semanticModel)
        {
            var type           = GetTypeInfo(statement, semanticModel);
            var currentClass   = statement.Ancestors().OfType <ClassDeclarationSyntax>().First();
            var declaredSymbol = semanticModel.GetDeclaredSymbol(currentClass);

            if (!HasVisibleConstructor(type, declaredSymbol))
            {
                return(false);
            }
            return(true);
        }
コード例 #5
0
            private void StoreVisitData(StatementSyntax node, List <StatementSyntax> conditionalCollection,
                                        List <StatementSyntax> unconditionalCollection)
            {
                var ancestors = node
                                .Ancestors()
                                .TakeWhile(n => !rootExpression.Equals(n))
                                .ToList();

                if (ancestors.Any(n => n.IsAnyKind(lambdaOrLoop)))
                {
                    return;
                }

                if (ancestors.Any(n => n.IsAnyKind(conditionalStatements)))
                {
                    conditionalCollection.Add(node);
                }
                else
                {
                    unconditionalCollection.Add(node);
                }
            }
コード例 #6
0
        // replaces the start span statement
        private async Task<Document> ReplaceStartSpanAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            var methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();
            string identifierString = CodeFixHelper.GetIfKeywordName(methodDeclaration.Body);
            SyntaxNode startSpan = CodeFixHelper.CreateEndOrStartSpan(generator, identifierString, "startDiagnosticSpan");

            return await ReplaceNode(declaration, startSpan.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.CarriageReturnLineFeed, SyntaxFactory.ParseLeadingTrivia("// Determines the start of the span of the diagnostic that will be reported, ie the start of the squiggle").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }
コード例 #7
0
        //replaces an incorrect diagnostic span statement
        private async Task<Document> ReplaceSpanAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            var methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();
            string startIdentifier = (methodDeclaration.Body.Statements[4] as LocalDeclarationStatementSyntax).Declaration.Variables[0].Identifier.Text;
            string endIdentifier = (methodDeclaration.Body.Statements[5] as LocalDeclarationStatementSyntax).Declaration.Variables[0].Identifier.Text;

            SyntaxNode span = CodeFixNodeCreator.CreateSpan(generator, startIdentifier, endIdentifier);

            return await ReplaceNode(declaration, span.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ParseLeadingTrivia("// The span is the range of integers that define the position of the characters the red squiggle will underline").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }
コード例 #8
0
        //replaces an incorrect open parenthsis statement
        private async Task<Document> ReplaceOpenParenAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            var methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();
            string expressionString = (methodDeclaration.Body.Statements[0] as LocalDeclarationStatementSyntax).Declaration.Variables[0].Identifier.Text;

            SyntaxNode openParen = CodeFixNodeCreator.CreateOpenParen(generator, expressionString);

            return await ReplaceNode(declaration, openParen.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ParseLeadingTrivia("// Extracts the opening parenthesis of the if-statement condition").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }
コード例 #9
0
        // replaces the diagnostic report statement
        private async Task<Document> ReplaceDiagnosticReportAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            var methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();

            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            string argumentName = CodeFixHelper.GetDiagnosticName(methodDeclaration);
            string contextName = CodeFixHelper.GetContextParameter(methodDeclaration);

            SyntaxNode diagnosticReport = CodeFixHelper.CreateDiagnosticReport(generator, argumentName, contextName);

            return await ReplaceNode(declaration, diagnosticReport.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.CarriageReturnLineFeed, SyntaxFactory.ParseLeadingTrivia("// Sends diagnostic information to the IDE to be shown to the user").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }
コード例 #10
0
        // replace the diagnostic creation statement
        private async Task<Document> ReplaceDiagnosticAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            var methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();
            var classDeclaration = methodDeclaration.Ancestors().OfType<ClassDeclarationSyntax>().First();

            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            string locationName = CodeFixHelper.GetLocationName(methodDeclaration);
            string ruleName = CodeFixHelper.GetFirstRuleName(classDeclaration);
            if (ruleName == null)
            {
                return document;
            }

            SyntaxNode diagnostic = CodeFixHelper.CreateDiagnostic(generator, locationName, ruleName);

            return await ReplaceNode(declaration, diagnostic.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.CarriageReturnLineFeed, SyntaxFactory.ParseLeadingTrivia("// Holds the diagnostic and all necessary information to be reported").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }
コード例 #11
0
        // replaces the open paren statement
        private async Task<Document> ReplaceOpenParenAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            MethodDeclarationSyntax methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();
            string expressionString = CodeFixHelper.GetIfStatementName(methodDeclaration.Body);

            SyntaxNode openParen = CodeFixHelper.CreateOpenParen(generator, expressionString);

            return await ReplaceNode(declaration, openParen.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.CarriageReturnLineFeed, SyntaxFactory.ParseLeadingTrivia("// Extracts the opening parenthesis of the if-statement condition").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document).ConfigureAwait(false);
        }
コード例 #12
0
        // replaces the location statement
        private async Task<Document> ReplaceLocationAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            MethodDeclarationSyntax methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();
            string ifStatementIdentifier = CodeFixHelper.GetIfStatementName(methodDeclaration.Body);
            string spanIdentifier = CodeFixHelper.GetSpanName(methodDeclaration);
            SyntaxNode location = CodeFixHelper.CreateLocation(generator, ifStatementIdentifier, spanIdentifier);

            return await ReplaceNode(declaration, location.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.CarriageReturnLineFeed, SyntaxFactory.ParseLeadingTrivia("// Uses the span created above to create a location for the diagnostic squiggle to appear within the syntax tree passed in as an argument").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document).ConfigureAwait(false);
        }
コード例 #13
0
        // replaces the span statement
        private async Task<Document> ReplaceSpanAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            MethodDeclarationSyntax methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();
            string startIdentifier = CodeFixHelper.GetStartSpanName(methodDeclaration);
            string endIdentifier = CodeFixHelper.GetEndSpanName(methodDeclaration);

            SyntaxNode span = CodeFixHelper.CreateSpan(generator, startIdentifier, endIdentifier);

            return await ReplaceNode(declaration, span.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.CarriageReturnLineFeed, SyntaxFactory.ParseLeadingTrivia("// The span is the range of integers that define the position of the characters the red squiggle will underline").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document).ConfigureAwait(false);
        }
コード例 #14
0
        // replaces the end span statement
        private async Task<Document> ReplaceEndSpanAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            MethodDeclarationSyntax methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();
            string identifierString = CodeFixHelper.GetOpenParenName(methodDeclaration);

            SyntaxNode endSpan = CodeFixHelper.CreateEndOrStartSpan(generator, identifierString, "endDiagnosticSpan");

            return await ReplaceNode(declaration, endSpan.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.CarriageReturnLineFeed, SyntaxFactory.ParseLeadingTrivia("// Determines the end of the span of the diagnostic that will be reported").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document).ConfigureAwait(false);
        }
コード例 #15
0
        private async Task<Document> ReplaceDiagnosticReportAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            var methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();

            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            string argumentName = (methodDeclaration.Body.Statements[8] as LocalDeclarationStatementSyntax).Declaration.Variables[0].Identifier.Text;
            string contextName = (methodDeclaration.ParameterList.Parameters[0].Identifier.Text);

            SyntaxNode diagnosticReport = CodeFixNodeCreator.CreateDiagnosticReport(generator, argumentName, contextName);

            return await ReplaceNode(declaration, diagnosticReport.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ParseLeadingTrivia("// Sends diagnostic information to the IDE to be shown to the user").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }
コード例 #16
0
        private async Task<Document> ReplaceDiagnosticAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            var methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();
            var classDeclaration = methodDeclaration.Ancestors().OfType<ClassDeclarationSyntax>().First();

            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            string locationName = (methodDeclaration.Body.Statements[7] as LocalDeclarationStatementSyntax).Declaration.Variables[0].Identifier.Text;
            string ruleName = CodeFixNodeCreator.GetFirstRuleName(classDeclaration);

            var diagnostic = CodeFixNodeCreator.CreateDiagnostic(generator, locationName, ruleName);

            return await ReplaceNode(declaration, diagnostic.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ParseLeadingTrivia("// Holds the diagnostic and all necessary information to be reported").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }
コード例 #17
0
 // removes the invalid statement from the method
 private async Task<Document> InvalidStatementAsync(Document document, StatementSyntax declaration, CancellationToken c)
 {
     SyntaxNode newInitializeDeclaration = CodeFixHelper.RemoveStatement(declaration);
     return await ReplaceNode(declaration.Ancestors().OfType<MethodDeclarationSyntax>().First(), newInitializeDeclaration, document);
 }
コード例 #18
0
        //replace an incorrect end span statement
        private async Task<Document> ReplaceEndSpanAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            var methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();
            string identifierString = (methodDeclaration.Body.Statements[3] as LocalDeclarationStatementSyntax).Declaration.Variables[0].Identifier.Text;

            SyntaxNode endSpan = CodeFixNodeCreator.CreateEndOrStartSpan(generator, identifierString, "endDiagnosticSpan");

            return await ReplaceNode(declaration, endSpan.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ParseLeadingTrivia("// Determines the end of the span of the diagnostic that will be reported").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }
コード例 #19
0
 // removes the provided statement from the method that it is in
 protected internal static SyntaxNode RemoveStatement(StatementSyntax statement)
 {
     MethodDeclarationSyntax initializeDeclaration = statement.Ancestors().OfType<MethodDeclarationSyntax>().First();
     MethodDeclarationSyntax newInitializeDeclaration = initializeDeclaration.RemoveNode(statement, 0);
     return newInitializeDeclaration as SyntaxNode;
 }
コード例 #20
0
        //replace an incorrect diagnostic location statement
        private async Task<Document> ReplaceLocationAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            var methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();
            string ifStatementIdentifier = (methodDeclaration.Body.Statements[0] as LocalDeclarationStatementSyntax).Declaration.Variables[0].Identifier.Text;
            string spanIdentifier = (methodDeclaration.Body.Statements[6] as LocalDeclarationStatementSyntax).Declaration.Variables[0].Identifier.Text;

            SyntaxNode location = CodeFixNodeCreator.CreateLocation(generator, ifStatementIdentifier, spanIdentifier);

            return await ReplaceNode(declaration, location.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ParseLeadingTrivia("// Uses the span created above to create a location for the diagnostic squiggle to appear within the syntax tree passed in as an argument").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }
コード例 #21
0
        // replaces the if statement variable
        private async Task<Document> IncorrectIfAsync(Document document, StatementSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            MethodDeclarationSyntax methodDeclaration = declaration.Ancestors().OfType<MethodDeclarationSyntax>().First();
            string name = CodeFixHelper.GetContextParameter(methodDeclaration);
            SyntaxNode ifStatement = CodeFixHelper.IfHelper(generator, name);

            return await ReplaceNode(declaration, ifStatement.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ParseLeadingTrivia("// The SyntaxNode found by the Initialize method should be cast to the expected type. Here, this type is IfStatementSyntax").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }