private static void AnalyzeDeclaration(
     SyntaxNodeAnalysisContext context,
     SyntaxList <MemberDeclarationSyntax> members,
     SyntaxToken openBrace,
     SyntaxToken closeBrace)
 {
     if (members.Any())
     {
         AnalyzeStart(context, members.First(), openBrace);
         AnalyzeEnd(context, members.Last(), closeBrace);
     }
     else
     {
         AnalyzeEmptyBraces(context, openBrace, closeBrace);
     }
 }
예제 #2
0
        internal override ImmutableArray <LocalSymbol> GetDeclaredLocalsForScope(CSharpSyntaxNode node)
        {
            if (node.Kind() == SyntaxKind.Block)
            {
                if (((BlockSyntax)node).Statements == _statements)
                {
                    return(this.Locals);
                }
            }
            else if (_statements.Count == 1 && _statements.First() == node)
            {
                return(this.Locals);
            }

            throw ExceptionUtilities.Unreachable;
        }
        public static void AnalyzeBlock(SyntaxNodeAnalysisContext context)
        {
            var block = (BlockSyntax)context.Node;

            SyntaxList <StatementSyntax> statements = block.Statements;

            if (statements.Any())
            {
                AnalyzeStart(context, statements.First(), block.OpenBraceToken);
                AnalyzeEnd(context, statements.Last(), block.CloseBraceToken);
            }
            else
            {
                AnalyzeEmptyBraces(context, block.OpenBraceToken, block.CloseBraceToken);
            }
        }
예제 #4
0
        private static SyntaxList <StatementSyntax> GetStatements(SwitchSectionSyntax prev)
        {
            SyntaxList <StatementSyntax> statements = prev.Statements;

            if (statements.Count == 1)
            {
                StatementSyntax firstStatement = statements.First();

                if (firstStatement.IsKind(SyntaxKind.Block))
                {
                    return(((BlockSyntax)firstStatement).Statements);
                }
            }

            return(statements);
        }
예제 #5
0
        public static Task <Document> RefactorAsync(
            Document document,
            UnsafeStatementSyntax unsafeStatement,
            SyntaxNode containingNode,
            CancellationToken cancellationToken)
        {
            SyntaxToken keyword = unsafeStatement.UnsafeKeyword;

            BlockSyntax block = unsafeStatement.Block;

            SyntaxList <StatementSyntax> statements = block.Statements;

            SyntaxNode newNode = null;

            int count = statements.Count;

            if (count == 0)
            {
                newNode = containingNode.RemoveNode(unsafeStatement);
            }
            else
            {
                StatementSyntax first = statements.First();
                StatementSyntax last  = statements.Last();

                SyntaxTriviaList leadingTrivia = keyword.LeadingTrivia
                                                 .AddRange(keyword.TrailingTrivia.EmptyIfWhitespace())
                                                 .AddRange(block.GetLeadingTrivia().EmptyIfWhitespace())
                                                 .AddRange(block.OpenBraceToken.TrailingTrivia.EmptyIfWhitespace())
                                                 .AddRange(first.GetLeadingTrivia().EmptyIfWhitespace());

                SyntaxTriviaList trailingTrivia = last.GetTrailingTrivia().EmptyIfWhitespace()
                                                  .AddRange(block.CloseBraceToken.LeadingTrivia.EmptyIfWhitespace())
                                                  .AddRange(block.GetTrailingTrivia());

                statements = statements
                             .ReplaceAt(0, first.WithLeadingTrivia(leadingTrivia))
                             .ReplaceAt(count - 1, last.WithTrailingTrivia(trailingTrivia));

                newNode = containingNode.ReplaceNode(unsafeStatement, statements.Select(f => f.WithFormatterAnnotation()));
            }

            newNode = newNode.InsertModifier(SyntaxKind.UnsafeKeyword);

            return(document.ReplaceNodeAsync(containingNode, newNode, cancellationToken));
        }
        public IEnumerable <TNode> AugmentWithInstrumentationStatements <TNode>(SyntaxList <TNode> list) where TNode : SyntaxNode
        {
            foreach (var node in list)
            {
                if (IsEntryPoint(node) && node == list.First() && _variableLocations.Data.Count > 0)
                {
                    yield return((TNode)(SyntaxNode)CreateStatementToPrintVariableLocations());
                }

                if (_instrumentedNodes.Contains(node) && _augmentations.Data.Count > 0)
                {
                    yield return((TNode)(SyntaxNode)CreateStatementToPrintAugmentations(node));
                }

                yield return((TNode)Visit(node));
            }
        }
        private static AccessorListSyntax AddNewLineAfterFirstAccessorIfNecessary(AccessorListSyntax accessorList, AccessorListSyntax newAccessorList, CancellationToken cancellationToken)
        {
            SyntaxList <AccessorDeclarationSyntax> accessors = newAccessorList.Accessors;

            if (accessors.Count > 1)
            {
                AccessorDeclarationSyntax accessor = accessors.First();

                SyntaxTriviaList trailingTrivia = accessor.GetTrailingTrivia();

                if (accessorList.SyntaxTree.IsSingleLineSpan(trailingTrivia.Span, cancellationToken))
                {
                    return(newAccessorList.ReplaceNode(accessor, accessor.AppendToTrailingTrivia(NewLineTrivia())));
                }
            }

            return(newAccessorList);
        }
        private static void ReportIssue(SyntaxList <StatementSyntax> statementsToReport, SyntaxList <StatementSyntax> locationProvider,
                                        SyntaxNodeAnalysisContext context, string constructType)
        {
            var firstStatement = statementsToReport.FirstOrDefault();

            if (firstStatement == null)
            {
                return;
            }

            var lastStatement = statementsToReport.Last();

            var location = Location.Create(context.Node.SyntaxTree,
                                           TextSpan.FromBounds(firstStatement.SpanStart, lastStatement.Span.End));

            context.ReportDiagnosticWhenActive(Diagnostic.Create(rule,
                                                                 location, locationProvider.First().GetLineNumberToReport(), constructType));
        }
예제 #9
0
        private bool IsMatchingScopeDesignator(CSharpSyntaxNode scopeDesignator)
        {
            if (scopeDesignator.Kind() == SyntaxKind.Block)
            {
                if (((BlockSyntax)scopeDesignator).Statements == _statements)
                {
                    return(true);
                }
            }
            else if (_statements.Count == 1 && _statements.First() == scopeDesignator)
            {
                // This code compensates for the fact that we fake an enclosing block
                // when there is an (illegal) local declaration as a controlled statement.
                return(true);
            }

            return(false);
        }
예제 #10
0
        public static bool SpanContainsDirectives <TNode>(this SyntaxList <TNode> list) where TNode : SyntaxNode
        {
            if (!list.Any())
            {
                return(false);
            }

            for (int i = 1; i < list.Count - 1; i++)
            {
                if (list[i].ContainsDirectives)
                {
                    return(true);
                }
            }

            return(list.First().SpanOrLeadingTriviaContainsDirectives() ||
                   list.Last().SpanOrTrailingTriviaContainsDirectives());
        }
예제 #11
0
        private static Task <Document> RefactorAsync(
            Document document,
            SyntaxListSelection <SwitchLabelSyntax> selectedLabels,
            IComparer <SwitchLabelSyntax> comparer,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxList <SwitchLabelSyntax> labels = selectedLabels.UnderlyingList;

            SyntaxList <SwitchLabelSyntax> newLabels = labels.ReplaceRange(
                selectedLabels.FirstIndex,
                selectedLabels.Count,
                selectedLabels.OrderBy(f => f, comparer));

            var section = (SwitchSectionSyntax)labels.First().Parent;

            SwitchSectionSyntax newSection = section.WithLabels(newLabels);

            return(document.ReplaceNodeAsync(section, newSection, cancellationToken));
        }
        private void AnalyzeAccessorDeclaration(SyntaxNodeAnalysisContext context)
        {
            var accessor = (AccessorDeclarationSyntax)context.Node;

            if (accessor.ExpressionBody == null &&
                !accessor.AttributeLists.Any())
            {
                BlockSyntax body = accessor.Body;

                ExpressionSyntax expression = UseExpressionBodiedMemberRefactoring.GetExpression(body);

                if (expression != null &&
                    expression.IsSingleLine())
                {
                    var accessorList = accessor.Parent as AccessorListSyntax;

                    if (accessorList != null)
                    {
                        SyntaxList <AccessorDeclarationSyntax> accessors = accessorList.Accessors;

                        if (accessors.Count == 1 &&
                            accessors.First().IsKind(SyntaxKind.GetAccessorDeclaration))
                        {
                            if (accessorList.DescendantTrivia().All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                            {
                                ReportDiagnostic(context, accessorList, expression);
                                context.ReportToken(FadeOutDescriptor, accessor.Keyword);
                                context.ReportBraces(FadeOutDescriptor, body);
                            }

                            return;
                        }
                    }

                    if (accessor.DescendantTrivia().All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                    {
                        ReportDiagnostic(context, body, expression);
                    }
                }
            }
        }
예제 #13
0
        public static void Analyze(SyntaxNodeAnalysisContext context, SwitchSectionSyntax switchSection)
        {
            SyntaxList <StatementSyntax> statements = switchSection.Statements;

            if (statements.Any())
            {
                SyntaxList <SwitchLabelSyntax> labels = switchSection.Labels;

                if (labels.Any())
                {
                    StatementSyntax statement = statements.First();

                    if (switchSection.SyntaxTree.IsSingleLineSpan(TextSpan.FromBounds(labels.Last().Span.End, statement.SpanStart)))
                    {
                        context.ReportDiagnostic(
                            DiagnosticDescriptors.FormatSwitchSectionStatementOnSeparateLine,
                            statement);
                    }
                }
            }
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            SwitchSectionSyntax switchSection,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxList <SwitchLabelSyntax> labels = switchSection.Labels;

            SwitchLabelSyntax defaultLabel = labels.First(f => f.IsKind(SyntaxKind.DefaultSwitchLabel));

            int index = labels.IndexOf(defaultLabel);

            SwitchLabelSyntax lastLabel = labels.Last();

            labels = labels.Replace(lastLabel, defaultLabel.WithTriviaFrom(lastLabel));

            labels = labels.Replace(labels[index], lastLabel.WithTriviaFrom(defaultLabel));

            SwitchSectionSyntax newSwitchSection = switchSection.WithLabels(labels);

            return(await document.ReplaceNodeAsync(switchSection, newSwitchSection, cancellationToken).ConfigureAwait(false));
        }
        public static void ComputeRefactoring(RefactoringContext context, TypeParameterConstraintClauseSyntax constraintClause)
        {
            GenericInfo genericInfo = SyntaxInfo.GenericInfo(constraintClause);

            if (!genericInfo.Success)
            {
                return;
            }

            SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = genericInfo.ConstraintClauses;

            if (constraintClauses.IsSingleLine())
            {
                if (constraintClauses.Count > 1)
                {
                    context.RegisterRefactoring(
                        "Format constraints on separate lines",
                        cancellationToken =>
                    {
                        GenericInfo newInfo = ToMultiLine(genericInfo);

                        return(context.Document.ReplaceNodeAsync(genericInfo.Node, newInfo.Node, cancellationToken));
                    },
                        RefactoringIdentifiers.FormatConstraintClauses);
                }
            }
            else if (constraintClause.DescendantTrivia(constraintClause.Span).All(f => f.IsWhitespaceOrEndOfLineTrivia()) &&
                     constraintClauses.First().GetFirstToken().GetPreviousToken().TrailingTrivia.IsEmptyOrWhitespace())
            {
                context.RegisterRefactoring(
                    "Format constraints on a single line",
                    cancellationToken =>
                {
                    GenericInfo newInfo = ToSingleLine(genericInfo);

                    return(context.Document.ReplaceNodeAsync(genericInfo.Node, newInfo.Node, cancellationToken));
                },
                    RefactoringIdentifiers.FormatConstraintClauses);
            }
        }
예제 #16
0
        private static bool IsSummaryMissing(XmlElementSyntax summaryElement)
        {
            SyntaxList <XmlNodeSyntax> content = summaryElement.Content;

            if (content.Count == 0)
            {
                return(true);
            }
            else if (content.Count == 1)
            {
                XmlNodeSyntax node = content.First();

                if (node.IsKind(SyntaxKind.XmlText))
                {
                    var xmlText = (XmlTextSyntax)node;

                    return(xmlText.TextTokens.All(IsWhitespaceOrNewLine));
                }
            }

            return(false);
        }
예제 #17
0
        public static Task <Document> RefactorAsync(
            Document document,
            UnsafeStatementSyntax unsafeStatement,
            CancellationToken cancellationToken)
        {
            SyntaxToken keyword = unsafeStatement.UnsafeKeyword;

            BlockSyntax block = unsafeStatement.Block;

            SyntaxToken openBrace  = block.OpenBraceToken;
            SyntaxToken closeBrace = block.CloseBraceToken;

            SyntaxList <StatementSyntax> statements = block.Statements;

            StatementSyntax firstStatement = statements.First();

            IEnumerable <SyntaxTrivia> leadingTrivia = keyword
                                                       .TrailingTrivia.EmptyIfWhitespace()
                                                       .Concat(openBrace.LeadingTrivia.EmptyIfWhitespace())
                                                       .Concat(openBrace.TrailingTrivia.EmptyIfWhitespace())
                                                       .Concat(firstStatement.GetLeadingTrivia().EmptyIfWhitespace());

            leadingTrivia = keyword.LeadingTrivia.AddRange(leadingTrivia);

            statements = statements.ReplaceAt(0, firstStatement.WithLeadingTrivia(leadingTrivia));

            StatementSyntax lastStatement = statements.Last();

            IEnumerable <SyntaxTrivia> trailingTrivia = lastStatement
                                                        .GetTrailingTrivia().EmptyIfWhitespace()
                                                        .Concat(closeBrace.LeadingTrivia.EmptyIfWhitespace())
                                                        .Concat(closeBrace.TrailingTrivia.EmptyIfWhitespace());

            trailingTrivia = closeBrace.TrailingTrivia.InsertRange(0, trailingTrivia);

            statements = statements.ReplaceAt(statements.Count - 1, lastStatement.WithTrailingTrivia(trailingTrivia));

            return(document.ReplaceNodeAsync(unsafeStatement, statements, cancellationToken));
        }
예제 #18
0
        private static BinaryExpressionSyntax GetIsExpression(CSharpSyntaxNode body)
        {
            switch (body?.Kind())
            {
            case SyntaxKind.IsExpression:
            {
                return((BinaryExpressionSyntax)body);
            }

            case SyntaxKind.Block:
            {
                var block = (BlockSyntax)body;

                SyntaxList <StatementSyntax> statements = block.Statements;

                if (statements.Count == 1)
                {
                    StatementSyntax statement = statements.First();

                    if (statement.IsKind(SyntaxKind.ReturnStatement))
                    {
                        var returnStatement = (ReturnStatementSyntax)statement;

                        ExpressionSyntax returnExpression = returnStatement.Expression;

                        if (returnExpression?.IsKind(SyntaxKind.IsExpression) == true)
                        {
                            return((BinaryExpressionSyntax)returnExpression);
                        }
                    }
                }

                break;
            }
            }

            return(null);
        }
예제 #19
0
        private static StatementSyntax GetStatement(StatementSyntax statement)
        {
            if (statement != null)
            {
                if (statement.IsKind(SyntaxKind.Block))
                {
                    var block = (BlockSyntax)statement;

                    SyntaxList <StatementSyntax> statements = block.Statements;

                    if (statements.Count == 1)
                    {
                        return(statements.First());
                    }
                }
                else
                {
                    return(statement);
                }
            }

            return(null);
        }
예제 #20
0
        public SyntaxList <AttributeListSyntax> Remove()
        {
            var attributes = _attributeList.First(a =>
                                                  a.Attributes.Any(at =>
                                                                   at.Name.ToString().Equals(_attributeText, StringComparison.OrdinalIgnoreCase)));

            if (attributes.Attributes.Count == 1 && _attributeList.Count == 1)
            {
                return(new SyntaxList <AttributeListSyntax>());
            }

            if (attributes.Attributes.Count == 1)
            {
                return(_attributeList.Remove(attributes));
            }

            var attribute = attributes.Attributes.First(at =>
                                                        at.Name.ToString().Equals(_attributeText, StringComparison.OrdinalIgnoreCase));

            var newAttributes = attributes.WithAttributes(attributes.Attributes.Remove(attribute));

            return(_attributeList.Replace(attributes, newAttributes));
        }
예제 #21
0
        private ClassDeclarationSyntax WrapMembersWithComment(ClassDeclarationSyntax node, SyntaxList <MemberDeclarationSyntax> members)
        {
            if (members.Count == 0)
            {
                node = node.WithOpenBraceToken(GetOpenBraceTokenWithEmptyCustomCode())
                       .WithMembers(SyntaxFactory.List <MemberDeclarationSyntax>());
            }
            else if (members.Count == 1)
            {
                var newMember = AddLeadingTriviaComment(AddTrailingTriviaComment(members.Single()));
                node = node.WithMembers(members.RemoveAt(0).Add(newMember));
            }
            else
            {
                var firstMember = AddLeadingTriviaComment(members.First());

                var lastMember    = AddTrailingTriviaComment(members.Last());
                var lastMemberIdx = members.Count - 1;

                node = node.WithMembers(members.RemoveAt(lastMemberIdx).RemoveAt(0).Insert(0, firstMember).Add(lastMember));
            }

            return(node);
        }
        private static CodeAction CreateCodeAction(Document document, Diagnostic diagnostic, IfStatementSyntax ifStatement, SyntaxList <StatementSyntax> statements)
        {
            return(CodeAction.Create(
                       Title,
                       cancellationToken =>
            {
                StatementSyntax firstStatement = statements.First();

                StatementSyntax newFirstStatement = firstStatement
                                                    .WithLeadingTrivia(ifStatement.GetLeadingTrivia().AddRange(firstStatement.GetLeadingTrivia().EmptyIfWhitespace()));

                statements = statements.Replace(firstStatement, newFirstStatement);

                StatementSyntax lastStatement = statements.Last();

                StatementSyntax newLastStatement = lastStatement
                                                   .WithTrailingTrivia(lastStatement.GetTrailingTrivia().EmptyIfWhitespace().AddRange(ifStatement.GetTrailingTrivia()));

                statements = statements.Replace(lastStatement, newLastStatement);

                return document.ReplaceNodeAsync(ifStatement, statements, cancellationToken);
            },
                       GetEquivalenceKey(diagnostic)));
        }
 private static SwitchLabelSyntax SingleOrDefaultSwitchLabel(SyntaxList <SwitchLabelSyntax> labels)
 {
     return(labels.Count == 1
         ? labels[0]
         : labels.First(x => x.IsKind(SyntaxKind.DefaultSwitchLabel)));
 }
예제 #24
0
        public static SyntaxNode RemoveConstraintClauses(SyntaxNode node)
        {
            switch (node.Kind())
            {
            case SyntaxKind.ClassDeclaration:
            {
                var classDeclaration = (ClassDeclarationSyntax)node;

                SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = classDeclaration.ConstraintClauses;

                if (!constraintClauses.Any())
                {
                    break;
                }

                TypeParameterConstraintClauseSyntax first = constraintClauses.First();

                SyntaxToken token = first.WhereKeyword.GetPreviousToken();

                SyntaxTriviaList trivia = token.TrailingTrivia.EmptyIfWhitespace()
                                          .AddRange(first.GetLeadingTrivia().EmptyIfWhitespace())
                                          .AddRange(constraintClauses.Last().GetTrailingTrivia());

                return(classDeclaration
                       .ReplaceToken(token, token.WithTrailingTrivia(trivia))
                       .WithConstraintClauses(default(SyntaxList <TypeParameterConstraintClauseSyntax>)));
            }

            case SyntaxKind.InterfaceDeclaration:
            {
                var interfaceDeclaration = (InterfaceDeclarationSyntax)node;

                SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = interfaceDeclaration.ConstraintClauses;

                if (!constraintClauses.Any())
                {
                    break;
                }

                TypeParameterConstraintClauseSyntax first = constraintClauses.First();

                SyntaxToken token = first.WhereKeyword.GetPreviousToken();

                SyntaxTriviaList trivia = token.TrailingTrivia.EmptyIfWhitespace()
                                          .AddRange(first.GetLeadingTrivia().EmptyIfWhitespace())
                                          .AddRange(constraintClauses.Last().GetTrailingTrivia());

                return(interfaceDeclaration
                       .ReplaceToken(token, token.WithTrailingTrivia(trivia))
                       .WithConstraintClauses(default(SyntaxList <TypeParameterConstraintClauseSyntax>)));
            }

            case SyntaxKind.StructDeclaration:
            {
                var structDeclaration = (StructDeclarationSyntax)node;

                SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = structDeclaration.ConstraintClauses;

                if (!constraintClauses.Any())
                {
                    break;
                }

                TypeParameterConstraintClauseSyntax first = constraintClauses.First();

                SyntaxToken token = first.WhereKeyword.GetPreviousToken();

                SyntaxTriviaList trivia = token.TrailingTrivia.EmptyIfWhitespace()
                                          .AddRange(first.GetLeadingTrivia().EmptyIfWhitespace())
                                          .AddRange(constraintClauses.Last().GetTrailingTrivia());

                return(structDeclaration
                       .ReplaceToken(token, token.WithTrailingTrivia(trivia))
                       .WithConstraintClauses(default(SyntaxList <TypeParameterConstraintClauseSyntax>)));
            }

            case SyntaxKind.DelegateDeclaration:
            {
                var delegateDeclaration = (DelegateDeclarationSyntax)node;

                SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = delegateDeclaration.ConstraintClauses;

                if (!constraintClauses.Any())
                {
                    break;
                }

                TypeParameterConstraintClauseSyntax first = constraintClauses.First();

                SyntaxToken token = first.WhereKeyword.GetPreviousToken();

                SyntaxTriviaList trivia = token.TrailingTrivia.EmptyIfWhitespace()
                                          .AddRange(first.GetLeadingTrivia().EmptyIfWhitespace())
                                          .AddRange(constraintClauses.Last().GetTrailingTrivia());

                return(delegateDeclaration
                       .ReplaceToken(token, token.WithTrailingTrivia(trivia))
                       .WithConstraintClauses(default(SyntaxList <TypeParameterConstraintClauseSyntax>)));
            }

            case SyntaxKind.MethodDeclaration:
            {
                var methodDeclaration = (MethodDeclarationSyntax)node;

                SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = methodDeclaration.ConstraintClauses;

                if (!constraintClauses.Any())
                {
                    break;
                }

                TypeParameterConstraintClauseSyntax first = constraintClauses.First();

                SyntaxToken token = first.WhereKeyword.GetPreviousToken();

                SyntaxTriviaList trivia = token.TrailingTrivia.EmptyIfWhitespace()
                                          .AddRange(first.GetLeadingTrivia().EmptyIfWhitespace())
                                          .AddRange(constraintClauses.Last().GetTrailingTrivia());

                return(methodDeclaration
                       .ReplaceToken(token, token.WithTrailingTrivia(trivia))
                       .WithConstraintClauses(default(SyntaxList <TypeParameterConstraintClauseSyntax>)));
            }

            case SyntaxKind.LocalFunctionStatement:
            {
                var localFunctionStatement = (LocalFunctionStatementSyntax)node;

                SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = localFunctionStatement.ConstraintClauses;

                if (!constraintClauses.Any())
                {
                    break;
                }

                TypeParameterConstraintClauseSyntax first = constraintClauses.First();

                SyntaxToken token = first.WhereKeyword.GetPreviousToken();

                SyntaxTriviaList trivia = token.TrailingTrivia.EmptyIfWhitespace()
                                          .AddRange(first.GetLeadingTrivia().EmptyIfWhitespace())
                                          .AddRange(constraintClauses.Last().GetTrailingTrivia());

                return(localFunctionStatement
                       .ReplaceToken(token, token.WithTrailingTrivia(trivia))
                       .WithConstraintClauses(default(SyntaxList <TypeParameterConstraintClauseSyntax>)));
            }
            }

            return(node);
        }
예제 #25
0
 public static AttributeListSyntax WithStepAttribute(this SyntaxList <AttributeListSyntax> list)
 {
     return(list.First(syntax => GetStepAttribute(syntax.Attributes) != null));
 }
예제 #26
0
 public static bool IsFirst <TNode>(this SyntaxList <TNode> list, TNode node) where TNode : SyntaxNode
 {
     return(list.Any() &&
            list.First() == node);
 }
예제 #27
0
        private void VisitMethods(SyntaxNodeAnalysisContext ctx)
        {
            if (!(ctx.Node is CSharpSyntax.ClassDeclarationSyntax node))
            {
                return;
            }

            var classSymbol = CSharp.CSharpExtensions.GetDeclaredSymbol(ctx.SemanticModel, node);

            if (classSymbol == null ||
                !classSymbol.IsDerivedFrom(ControllerNames))
            {
                return;
            }

            var methodsWithParameters = node.DescendantNodesAndSelf()
                                        .OfType <CSharpSyntax.MethodDeclarationSyntax>()
                                        .Where(method => method.ParameterList.Parameters.Any())
                                        .Where(method => method.Modifiers
                                               .Any(x => x.IsKind(CSharp.SyntaxKind.PublicKeyword)))
                                        .Where(method => ctx.SemanticModel
                                               .GetSymbolInfo(method.ReturnType)
                                               .Symbol
                                               ?.IsType("System.String") == true);

            foreach (CSharpSyntax.MethodDeclarationSyntax method in methodsWithParameters)
            {
                SyntaxList <CSharpSyntax.StatementSyntax> methodStatements = method.Body.Statements;
                var methodInvocations = method.DescendantNodes()
                                        .OfType <CSharpSyntax.InvocationExpressionSyntax>()
                                        .ToArray();

                if (!methodStatements.Any())
                {
                    continue;
                }

                DataFlowAnalysis flow = ctx.SemanticModel.AnalyzeDataFlow(methodStatements.First(),
                                                                          methodStatements.Last());

                // Returns from the Data Flow Analysis of input data
                // Dangerous data is: Data passed as a parameter that is also returned as is by the method
                var inputVariables = flow.DataFlowsIn.Union(flow.VariablesDeclared.Except(flow.AlwaysAssigned))
                                     .Union(flow.WrittenInside)
                                     .Intersect(flow.WrittenOutside)
                                     .ToArray();

                if (!inputVariables.Any())
                {
                    continue;
                }

                foreach (ISymbol inputVariable in inputVariables)
                {
                    bool inputVariableIsEncoded = false;
                    foreach (CSharpSyntax.InvocationExpressionSyntax methodInvocation in methodInvocations)
                    {
                        var arguments = methodInvocation.ArgumentList.Arguments;
                        if (!arguments.Any())
                        {
                            continue;
                        }

                        if (arguments.First().ToString().Contains(inputVariable.Name))
                        {
                            inputVariableIsEncoded = true;
                        }
                    }

                    if (!inputVariableIsEncoded)
                    {
                        ctx.ReportDiagnostic(Diagnostic.Create(Rule, inputVariable.Locations[0]));
                        break;
                    }
                }
            }
        }
 static SyntaxList<StatementSyntax> GenerateNewTrueStatement(SyntaxList<StatementSyntax> falseStatements)
 {
     if (falseStatements.Count == 1)
     {
         var stmt = falseStatements.First();
         if (stmt.GetLeadingTrivia().All(triva => triva.IsKind(SyntaxKind.WhitespaceTrivia)))
             return new SyntaxList<StatementSyntax>().Add(stmt);
     }
     return falseStatements;
 }
예제 #29
0
        public static void AnalyzerSwitchSection(SyntaxNodeAnalysisContext context)
        {
            var switchSection = (SwitchSectionSyntax)context.Node;

            if (!(switchSection.Statements.SingleOrDefault(shouldThrow: false) is BlockSyntax block))
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = block.Statements;

            SyntaxList <StatementSyntax> .Enumerator en = statements.GetEnumerator();

            if (!en.MoveNext())
            {
                return;
            }

            do
            {
                if (en.Current.IsKind(SyntaxKind.LocalDeclarationStatement))
                {
                    var localDeclaration = (LocalDeclarationStatementSyntax)en.Current;

                    if (localDeclaration.UsingKeyword.IsKind(SyntaxKind.UsingKeyword))
                    {
                        return;
                    }
                }
            } while (en.MoveNext());

            SyntaxToken openBrace = block.OpenBraceToken;

            if (!AnalyzeTrivia(openBrace.LeadingTrivia))
            {
                return;
            }

            if (!AnalyzeTrivia(openBrace.TrailingTrivia))
            {
                return;
            }

            if (!AnalyzeTrivia(statements.First().GetLeadingTrivia()))
            {
                return;
            }

            if (!AnalyzeTrivia(statements.Last().GetTrailingTrivia()))
            {
                return;
            }

            SyntaxToken closeBrace = block.CloseBraceToken;

            if (!AnalyzeTrivia(closeBrace.LeadingTrivia))
            {
                return;
            }

            if (!AnalyzeTrivia(closeBrace.TrailingTrivia))
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemoveUnnecessaryBraces, openBrace);
            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemoveUnnecessaryBracesFadeOut, closeBrace);

            bool AnalyzeTrivia(SyntaxTriviaList trivia)
            {
                return(trivia.All(f => f.IsKind(SyntaxKind.WhitespaceTrivia, SyntaxKind.EndOfLineTrivia, SyntaxKind.SingleLineCommentTrivia)));
            }
        }
 private TextSpan GetTextSpan <TSyntax>(SyntaxList <TSyntax> list)
     where TSyntax : SyntaxNode
 {
     return(TextSpan.FromBounds(list.First().FullSpan.Start, list.Last().FullSpan.End));
 }
        protected void VisitMethods(SyntaxNodeAnalysisContext ctx)
        {
            if (!(ctx.Node is VBSyntax.ClassBlockSyntax node))
            {
                return;
            }

            var classSymbol = VB.VisualBasicExtensions.GetDeclaredSymbol(ctx.SemanticModel, node);

            if (classSymbol == null ||
                !classSymbol.IsDerivedFrom("Microsoft.AspNetCore.Mvc.Controller", "System.Web.Mvc.Controller"))
            {
                return;
            }

            var methodsWithParameters = node.DescendantNodesAndSelf()
                                        .OfType <VBSyntax.MethodBlockSyntax>()
                                        .Where(method =>
                                               method.SubOrFunctionStatement.ParameterList.Parameters.Any())
                                        .Where(method => method
                                               .SubOrFunctionStatement
                                               .Modifiers.Any(x => x.IsKind(VB.SyntaxKind.PublicKeyword)))
                                        .Where(method =>
            {
                var retType = method.SubOrFunctionStatement.AsClause?.Type;
                if (retType == null)
                {
                    return(false);
                }

                return(ctx.SemanticModel
                       .GetSymbolInfo(retType)
                       .Symbol
                       ?.IsType("System.String") == true);
            });

            foreach (VBSyntax.MethodBlockSyntax method in methodsWithParameters)
            {
                SyntaxList <VBSyntax.StatementSyntax> methodStatements = method.Statements;
                var methodInvocations = method.DescendantNodes()
                                        .OfType <VBSyntax.InvocationExpressionSyntax>()
                                        .ToArray();

                if (!methodStatements.Any())
                {
                    continue;
                }

                DataFlowAnalysis flow = ctx.SemanticModel.AnalyzeDataFlow(methodStatements.First(),
                                                                          methodStatements.Last());

                // Returns from the Data Flow Analysis of sensible data
                // Sensible data is: Data passed as a parameter that is also returned as is by the method
                var sensibleVariables = flow.DataFlowsIn.Union(flow.VariablesDeclared.Except(flow.AlwaysAssigned))
                                        .Union(flow.WrittenInside)
                                        .Intersect(flow.WrittenOutside)
                                        .ToArray();

                if (!sensibleVariables.Any())
                {
                    continue;
                }

                foreach (ISymbol sensibleVariable in sensibleVariables)
                {
                    bool sensibleVariableIsEncoded = false;
                    foreach (VBSyntax.InvocationExpressionSyntax methodInvocation in methodInvocations)
                    {
                        var arguments = methodInvocation.ArgumentList.Arguments;
                        if (!arguments.Any())
                        {
                            continue;
                        }

                        if (arguments.First().ToString().Contains(sensibleVariable.Name))
                        {
                            sensibleVariableIsEncoded = true;
                        }
                    }

                    if (!sensibleVariableIsEncoded)
                    {
                        ctx.ReportDiagnostic(Diagnostic.Create(Rule, method.GetLocation()));
                    }
                }
            }
        }